{***************************************************************
    SpyGestion  Copyright (C) 2008 Christophe KOALI <nature2gas@gmail.com>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
****************************************************************}
unit modClasses;

interface


uses Classes,
     SysUtils,
     modCookies,
     modCore,
     modBaseType,

     HttpProt,

     Forms,
     Windows,

     ESBDates,
     sFonctionsChaines,
     sHTMLFonctions,
     modGestionDownload,
     modGestionDLGzip,

     modSockUtils,

     modClassRessources,
     modPlanete,
     modLinkOtherPlanet,
    
     modStatsPlayers,
     modMessagesList,
     modGalaxiePlanetes,


     WSocket,
     modGidToStr,     
     modParsingClassIHeader,
     modParsingClassIFlotte1,


     modParsingClassIMenuLeft,
     
     modParsingClassGestion,
     
     modProfilsForAttack,
     modParsingClassIStatistiques,
     
     modParsingClass,

     LibXmlParser, LibXmlComps;

     // Pour la recherche, on ne peut en faire qu'une seule
     // en même temps et sur une seule planète uniquement


(**
 On commence la partie avec 500 de métal et cristal,
 aucun batiment n'est construit, dans la liste des ressouces
 on a donc juste le revenu de base

 **)



(*****************************************************************

 Flag de débogage de fichier:
 - DEBUGFILE_FLAG
        pour activer les fonctions de debogage de fichier

 - DEBUGFILE_WHEN_ECHEC
        pour sauvegarder les pages dont le parsing echoue

 - DEBUGFILE_WHEN_SUCCESS
        pour sauvegarder les pages dont le parsing reussit

*******************************************************************)



{$IFDEF DEBUGFILE_FLAG}
const
     CNT_DEBUGFILE_MESSAGELIST = 'message_list';
     CNT_DEBUGFILE_FLOTTE1     = 'flotte1_';
     CNT_DEBUGFILE_FLOTTE2     = 'flotte2_';
     CNT_DEBUGFILE_FLOTTE3     = 'flotte3_';
     CNT_DEBUGFILE_FLOTTE4     = 'flotte4_';

     CNT_DEBUGFILE_APERCU      = 'apercu_';
     CNT_DEBUGFILE_RESSOURCES  = 'ressources_';

     CNT_DEBUGFILE_ELEMENT_BATIMENTS        = 'element_batiment_';
     CNT_DEBUGFILE_ELEMENT_RECHERCHE        = 'element_recherche_';
     CNT_DEBUGFILE_ELEMENT_CHANTIER_SPATIAL = 'element_chantier_';
     CNT_DEBUGFILE_ELEMENT_DEFENSE          = 'element_defense_';
     CNT_DEBUGFILE_ELEMENT_UNKNOW           = 'element_unkown_';

     CNT_DEBUGFILE_CHANGE_PLANETE           = 'changing_';


     CNT_DEBUGFILE_HEADER_INVALID           = 'header_';
{$ENDIF}




type
    TPlayerJob = (jobAucun,
                  jobLogin, jobUpdateAllElement,
                  jobUpdateElement, jobUpdateRessource,
                  jobUpdateAppercu, jobEverythingAllPlanete,
                  jobStatsCollect, jobGalaxyCollect,
                  jobChangePlanete);

    TPlayerJobOccup = (jobpAucun, jobpOccupe);



    TFlotteEnvoiRes = (ferFatalError, ferSocketError, ferShouldRetry, ferShouldRetryButNotError,
                       ferSuccess, ferNoVaisseaux, ferFlotteMaxAtteinte,
                       ferNotOrReLoginCertain,

                       ferPlaneteInvalid);


    TOGProxyType = (ptypeHttp, ptypeSock5, ptypeSock4, ptypeSock4a, ptypeDisable);


    TPlayerGestion = class;
    TCallBackOnItemsCostChange = procedure (Joueur: TPlayerGestion; Planete: TPlaneteInfo) of object;


    // Ceci n'est que la gestion d'un joueur
    // Il est ensuite géré soit par un humain avec le programme
    // soit par l'action manager
    // Il doit donc être 100% indépendant des deux situations
    TPlayerGestion = class(TObject)
    private
        FScanneurCommum: TEasyXmlScanner;

        // Liste des planètes (contient la liste des éléments constructible
        // et sont sauvegardés dans un fichier texte)
        FPlaneteList   : TListPlanet;

        // Planete sélectionnée dans la liste (peut donc valoir nil)
        FCurrentPlanete: TPlaneteInfo;


        // Protective Critical Section object
        ReadWriteCS: TRTLCriticalSection;


        // Fichier de sauvegarde
        FFichier : string;

        // Définit si le mot de passe est valide
        FPasswordIsInvalid: boolean;


        // sert pour le tunnel (exemple: http://game1029.de/game/ )
        // et permet de savoir si l'on est bien loggé
        FRemoteURLGameDir : string;
        FSessionId        : string;

        // Page de login (où se situe la liste des univers)
        FLogingUniversListPage: string;
        FLogingUniversListPageReferenceLink: string;

        //FLoginDirectOnGameServeur: boolean;
        //FLoginDirectURLServeur   : string;

        // login spécial pour l'uni béta...
        FSpecialLogin : boolean;
        

        FDebugWebPageDossier: string;

        {$IFDEF DEBUGFILE_FLAG}
           FDebugWebPageActive : boolean;
           FDebugWebPageActiveWhenSuccess: boolean;
        {$ENDIF}


        // Valeur a AJOUTER (ou soustraire si la valeur est négative)
        // à l'heure obtenu en parsant les pages web (comme flotte)
        // pour obtenir une heure locale
        FDifferenceHeureLocaleHeureServeur: int64;

        {$IFDEF DEBUG}
           // information de débogage totale
           FDebugProc: TsfcProcStatus;
        {$ENDIF}

        {$IFDEF DBGSTATUS}
           // Juste les informations de status
           FStatusProc: TsfcProcStatus;
        {$ENDIF}

        // Pour indiquer à l'utilisateur où en est le scan de la galaxie
        FStatusGalaxieScan: TsfcProcStatus;

        // Pareil mais pour le téléchargement des stats
        FStatusStatsScan: TsfcProcStatus;


        // Client HTTP
        FsockHTTP: THttpCli;

        // Sauvegarde des cookies
        FCookies : TCollectionCookieInfos;



        // Quand on change de planète, on vérifie si la page aperçu doit être
        // retélécharger (pour mettre à jour le nb de case occupée)
        // Cette variable empêche cette vérification
        FDontDLAppercuPageOnChangePlanet: boolean;


        // Pour connaitre les liens du menu, et pouvoir ainsi
        // se déplacer efficacement
        //FParserMenu     : TParsingMenuLeft;
        FDateMenuLoad   : int64;           // La page du menu doit être raffraichit toute les 30mins
        FDateMenuNbError: integer;

        // Pour la page de ressources
        //FParserRessource: TParsingPageRessource;

        // Pour la page d'apperçu
        //FParserApercu : TParsingAppercu;

        // Pour la page batiment, recherche, station spatial, défense
        //FParserElement: TParsingBatiment;



        FInLogin: boolean;

        // Pour que l'utilisateur puisse stopper la récolte des stats ou du scan de la galaxie
        FProcRecolteArret : boolean;


        FIsFuckingCompteCommandant: boolean;



        FMaxFlotteSlot   : integer;

        // Defini si le compte a les officier ou pas
        FExistOfficier: boolean;


        //
        // Auto relogin
        //

        // Après réflexion, un humain se relog immédiatement après avoir vu
        // le message lui disant de se relogger (d'autant plus que maintenant
        // on est redirigé sur la page de login d'ogame)
        // il est donc logique de se relogger IMMEDIATEMENT
        // (dans les dizaines de secondes qui suivent du moins)

        // planète sur laquelle changer lors de l'auto relogin
        // (généralement -1)
        //FReloginPlaneteLocation: TPlanetLocation;

        // délai d'attente d'auto relogin pour la construction automatique
        //FDelayToWaitForReloginForAutoConstruction: integer;

        // délai d'attente d'auto relogin pour l'alerte d'attaque
        //FDelayToWaitForReloginForAlerteAtt       : integer;

        FMustReloginDetected: boolean;
        FNextDateToRelog    : int64;


        // intervalle minimal entre chaque auto relogin
        FAutoReloginLastDate   : int64;




        procedure LoadLigne(Ligne: string);

        // Header de la dernière page
        //function GetLastHeaderClass: TParsingDebutDocumentMineraiAndPlanet;

        procedure DoStatusGalaxie(const Msg: string);
        procedure DoStatusStats(const Msg: string);

        function GetResultFromFlotteConfirmation(Cible: TPlanetLocation): TFlotteEnvoiRes;


        

        function GetRobotIsLogged: boolean;
        function GetRobotCanDoSomething: boolean;


        procedure SauvegardeRapportCombat(pe: POGMessage; PageWeb: string);



        procedure SetNewDebugProc(Value: TsfcProcStatus);




    protected
        // Pour pouvoir se logger
        FParserGetLogIn: TParsingLogInPage;

        // pour les stats
        //FParserStats: TParsingPlayerStats;

        // pour la galaxie
        //FParserGalaxie: TParsingGalaxie;


        // pour les flottes
        //FParserFlotte1Vaisseaux      : TParsingFlotte1_ChoixVaisseaux;
        //FParserFlotte2Destination    : TParsingFlotte2_ChoixDestination;
        //FParserFlotte3OrdreRessources: TParsingFlotte3_OrdreEtRessources;
        //FParserFlotte4Confirmation   : TParsingFlotte4_ConfirmationEnvoi;

        // Pour les messages
        //FParserMessagesList: TParsingMessagesList;

        // Pour connaitre la page de redirection, bien que
        // ce soit toujours la même, cela permet de savoir
        // surtout si le login s'est bien effectué
        FParserAfterPostLogin: TParsingAfterLogInPage;

        // Après avoir été redirigé, on tombe sur une frame
        // qui sépare l'écran en deux, le menu à gauche, et
        // le reste à droite.
        FParserFrame: TParsingFrameSet;


        // Dernière page web downloadé, peut être à nil
        //FLastPageWebDL: TParsingBaseGamePage;

        FParsingPages : TParsingGestion;

        //
        // Timer gestion
        //

        // Nombre de verouillage
        FLockTimerCount: integer;

        // Nombre d'entrée dans le timer
        FEnterTimerCount: integer;

        // Définit si on est dans le timer
        FInTimer   : boolean;

        FJobOccupation: TPlayerJobOccup;



        
        // à cause du tunnel, la planète sur laquelle le robot croit être
        // n'est pas forcément sur laquelle on est
        // avant ce n'était pas indispensable, mais avec l'évacuation
        // de flotte, on n'a pas plus droit à l'erreur
        function CheckCurrentPlanetFromHeader: boolean;




        procedure EnterTimer;
        procedure ExitTimer;

        function GetHeader: TParsingHeader;
        function GetFlotte1: TParsingFlotte1_ChoixVaisseaux;

        procedure SetDebugWebPageDossier(Valeur: string);

        {$IFDEF DEBUGFILE_FLAG}
           procedure DebugWebPage(Page: string; Titre: string);
        {$ENDIF}

        procedure DoDebugInt(s: string; v: integer); overload;
        procedure DoDebugInt(s: string; v: int64); overload;
        procedure DoDebugInt(s: string; v: boolean); overload;
        procedure DoDebugExtended(s: string; v: Extended);


    public
        DossierRapportCombat: string;

        // pour éviter d'obtenir plusieurs fois la même date unix entre procédure
        // quand on sait qu'elle a été calculé avant
        LastCurrDate        : int64;



        // Contenu de la page web (ce n'est pas le chemin vers un fichier)
        LoginLocalWebPage: string;
        LoginUseLocalWebPage: boolean;

        Conf: TProfilsAttack;
        


{$IFDEF OFFICIER_OK}
        AllowToWorkWithOfficier: boolean;
{$ENDIF}

        property ExistOfficier: boolean read FExistOfficier;


        // ATTENTION: ce verouillage désactive l'alerte d'attaque, l'évacuation de flotte, l'attaque automatique
        // c'est à dire TOUT ce qui est géré par le timer (dont aussi la construction automatique)
        function  LockTimer: boolean;
        procedure UnlockTimer;
        property IsInTimer: boolean read FInTimer;



        // Verrou de section critique
        procedure Lock;
        procedure Unlock;




        // Client HTTP
        property sockHTTP: THttpCli read FsockHTTP;

        property iCookies   : TCollectionCookieInfos read FCookies;
        property iURLGameDir: string                 read FRemoteURLGameDir;
        property iSessionId : string                 read FSessionId;
        property iMustRelogin: boolean               read FMustReloginDetected;


        // Telecharge une page web
        function myGETorPOST_InTamponX(URL, PostData: string; sckHttp: THttpCli): string;


        property IsLogged: boolean         read GetRobotIsLogged;
        property IsLoggedAndCanDoSomething: boolean read GetRobotCanDoSomething;

        property PasswordIsInvalid: boolean read FPasswordIsInvalid;


        // sert à présent aussi de cache pour la page de login
        property DebugWebPageDossier: string  read FDebugWebPageDossier write SetDebugWebPageDossier;

        {$IFDEF DEBUGFILE_FLAG}
           property DebugWebPageActive : boolean read FDebugWebPageActive  write FDebugWebPageActive;
           property DebugWebPageActiveWhenSuccess : boolean read FDebugWebPageActiveWhenSuccess  write FDebugWebPageActiveWhenSuccess;
        {$ENDIF}


        property IsInLogin: boolean read FInLogin;


        // Nombre maxi de slot de flotte possible
        property MaxSlot: integer read FMaxFlotteSlot;


        // Date de mise à jour du menu  gauche (si jamais loggé alors 0)
        property DateMenuLoad: int64 read FDateMenuLoad;

     //   function CanBuildThisGID(GID: integer): boolean;
     //   function BuildThisGID(GID: integer; Quantite: integer = 1): boolean;
        {$IFDEF DEBUG}
           property DebugProc: TsfcProcStatus read FDebugProc write SetNewDebugProc;
        {$ENDIF}


        property curLastHeader: TParsingHeader  read GetHeader;

        // auto relogin


        


        property DontDLAppercuPageOnChangePlanet : boolean read FDontDLAppercuPageOnChangePlanet write FDontDLAppercuPageOnChangePlanet;

        property StatusGalaxieProc: TsfcProcStatus read FStatusGalaxieScan write FStatusGalaxieScan;


        //function GetLastTypeClassDL: integer;

        property DifferenceHeureLocaleHeureServeur: int64 read FDifferenceHeureLocaleHeureServeur;

        property ProcRecolteArret : boolean read FProcRecolteArret write FProcRecolteArret;



        property lLoginUniversListPage               : string read FLogingUniversListPage write FLogingUniversListPage;
        property lLogingUniversListPageReferenceLink : string read FLogingUniversListPageReferenceLink write FLogingUniversListPageReferenceLink;
        property lSpecialLogin                       : boolean read FSpecialLogin write FSpecialLogin;




        property cParsing    : TParsingGestion read FParsingPages;

        //property cMenu      : TParsingMenuLeft      read FParserMenu;

        //property cApercu   : TParsingAppercu        read FParserApercu;

        //property cElement   : TParsingBatiment       read FParserElement;
        //property cRessources: TParsingPageRessource  read FParserRessource;
        property cFlotteVaisseaux: TParsingFlotte1_ChoixVaisseaux read GetFlotte1;
        //property cFlotteConfirm  : TParsingFlotte4_ConfirmationEnvoi read FParserFlotte4Confirmation;
        //property cMessagesList   : TParsingMessagesList           read FParserMessagesList;

        //property cGalaxie        : TParsingGalaxie     read FParserGalaxie;


        // ATTENTION: Peut être à nil
        property curPlanete   : TPlaneteInfo read FCurrentPlanete;
        property allPlanetes  : TListPlanet  read FPlaneteList;

        //property curLastHeader: TParsingDebutDocumentMineraiAndPlanet read GetLastHeaderClass;




        // On ne peut pas utiliser un timer par joueur, mais un timer pour tout
        // les joueurs, le signal est donc transmit à chaque joueur
        procedure OnTimer; virtual;
        function CanEnterInTimer: boolean;



        procedure UpdateInternalFromConf; virtual; abstract;



        // Effectue le login, télécharge donc le menu à gauche ainsi que la page
        // d'apperçu
        function ProceedLogin: integer; virtual;

        // Récolte les statistiques dans la base de données passées en paramètre
        function ProceedCollectStatsPlayer(cDatabase: TCollectionPlayerStats; dbType: TStatsType): integer;

        // Met à jour les galaxies
        function ProceedGalaxieScan(cDatabase: TCollectionGalaxiePlanete; Galaxie, SystemStart, SystemEnd: integer; UpdatePlusAncienQueCetteDate: int64): integer;

        // Met à jour les données 'élément' pour la planete en cours
        function ProceedUpdateAllElements: integer;
        function ProceedUpdateElement(IdFromMenu: TMenuLinkID; bDoUpdateItem: boolean = true): integer; virtual;

        // Lit tous les messages
        function ProceedGetMessagesList(ListMsg: TCollectionOGMessage; bDelMessageSite: boolean; bDownloadRapportCombat: boolean): integer;

        // Met tout à jour toutes les planètes
        function ProceedUpdateEverythingOnEveryPlanet(bForceAppercu: boolean = false): integer;
        function ProceedUpdateEveryBatimentOnEveryPlanet: integer;

        // Met à jour les données 'ressource' pour la planète en cours
        function ProceedUpdateRessource(bModifyAllList: boolean; bCalculRessources: boolean; FromThisURL: string = ''): integer;
        function ProceedRessourceCalcul: integer;
        function ProceedModifRessourcesActivity: integer;

        // Met à jour l'aperçu
        function ProceedUpdateApercu(bOverrideURLAndReference: boolean = false): integer; virtual;



        // Telecharge la page de flotte pour connaitre les vaisseaux disponible
        function RetreiveFlotte1Page(bSansParsing: boolean = false): integer; virtual;


        // Sonde UNE cible
        function ProceedSondage(Cible: TPlanetLocation; NbSondes: integer; iSpeedRatio: integer = 10): TFlotteEnvoiRes;

        // Attaque une cible
        function ProceedAttaque(Cible: TPlanetLocation; iSpeedRatio: integer = 10; bAttaqueLune: boolean = false): TFlotteEnvoiRes;


        // Sert pour l'évacuation de flotte rapide, en particulier quand on se fait phalanger
        // et que l'on doit évacuer la flotte en peu de temps
        // Particularités:
        // - TOUTES les ressources sont évacués (si possible)
        // - On sépcifie un nombre minimum de flotte pour effectuer l'évacuation
        // - Si l'ordre indiquer est introuvable, un autre est définit par défaut
        function ProceedFastEvacuation(Cible: TPlanetLocation; iSpeedRatio: integer; bWhere: TOGDestinationType; bMinVaisseaux: integer; xOrdre: TOGOrdre): TFlotteEnvoiRes;

        function ProceedEnvoiDeFlotte(Infos: PFlotteEnvoiData): TFlotteEnvoiRes;

        function ProceedReturnFlotte(FlotteID: PFlotteOwnUID): integer;




        // Change de planète, et charge la page correspondante
        // toute les actions suivantes s'effecturont sur cette planète
        function ChangePlanete(Nouvelle: TPlanetLocation; bForceAEtreCertainDetreDessus: boolean = false): integer;


        function SaveToFile(Fichier: string): integer;
        function LoadFromFile(Fichier: string): integer;


        function DownloadMenuLeft: integer;
        function DownloadMiscFiles(list: TStrings): integer;


        {$IFDEF DEBUG}
           procedure DoDebug(const Msg: string);
           procedure DoDebugStrings(x: TStrings);
        {$ENDIF}

        procedure DoStatus(const Msg: string);


        procedure DoSleep(const Duree: integer);

        constructor Create;
        destructor Destroy; override;


        // Efface toute les données sans pour autant libérer les classes
        //procedure MakeClean;

        // Efface tout (surtout les cookies)
        procedure Clear(bDelFichierSave: boolean); virtual;



        procedure ShowInternal; virtual;
        function GetCacheLoginPagePath: string;
        function DirectLoginPreloadCachePage: boolean;

    end;

    // TODO: faire une classe qui dérive de TPlayerGestion
    // qui gére le joueur automatiquement
    
const
   mcDL_MUST_RELOGIN = #9 + 'RELOGIN' + #245;


   function ExtractRedirRessourceURL(sPage: string): string;

implementation

uses
     modFlotteEnVoyage,
     modApercuMsg,
     modFormulesDuJeu,
     gnugettext;

type TRessourceRedirState = (trrsNeant, trrsHTTP302, trrsHTML, trrsHandled);


// Extrait la Location de redirection de l'header HTTP
function mcsExtractLocation(s: TStrings): string;
var i: integer;
    Ligne, sKey: string;
    xPos: integer;
begin

    Result := '';
    
    if s.Count = 0 then exit;

    for i := 0 to s.Count - 1 do begin
       Ligne := s.Strings[i];
       xPos := pos(':', Ligne);

       if xPos = 0 then
          Continue;

       sKey := copy(Ligne, 1, xPos - 1);
       if SameText(sKey, 'Location') then begin
          Result := trim(copy(Ligne, xPos + 1, maxint));
          exit;
       end;
    end;

end;




procedure TPlayerGestion.DoDebugInt(s: string; v: integer);
begin
    DoDebug(s + ': ' + IntToStr(v));
end;
procedure TPlayerGestion.DoDebugInt(s: string; v: int64);
begin
    DoDebug(s + ': ' + IntToStr(v));
end;
procedure TPlayerGestion.DoDebugInt(s: string; v: boolean);
begin
    DoDebug(s + ': ' + IntToStr(iif(v, 1, 0)));
end;
procedure TPlayerGestion.DoDebugExtended(s: string; v: Extended);
begin
    DoDebug(s + ': ' + FloatToStr(v));
end;



procedure TPlayerGestion.ShowInternal;
begin
    DoDebug('@@@@@ Général @@@@@');

    // pour CanEnterInTimer:
    DoDebug('InTimer: ' + IntToStr(iif(FInTimer, 1, 0)));
    DoDebug('InLogin: ' + IntToStr(iif(FInLogin, 1, 0)));
    DoDebug('Socket non prêt: ' + IntToStr(iif(FsockHTTP.State <> httpReady, 1, 0)));
    DoDebug('Job occupé: ' + IntToStr(iif(FJobOccupation <> jobpAucun, 1, 0)));
    DoDebug('Menu non loaded: ' + IntToStr(iif(FDateMenuLoad < 100, 1, 0)));

    DoDebugInt('*CEiT', CanEnterInTimer);

    DoDebugInt('Timer enter', FEnterTimerCount);
    DoDebugInt('Timer lock', FLockTimerCount);


    DoDebug('Game URL: ' + FRemoteURLGameDir);
    DoDebug('SessionId: ' + FSessionId);

    DoDebugInt('MaxSlot', MaxSlot);




end;

function TPlayerGestion.GetFlotte1: TParsingFlotte1_ChoixVaisseaux;
begin
    Result := FParsingPages.pFlotte1;
end;
function TPlayerGestion.GetHeader: TParsingHeader;
begin
    Result := FParsingPages.pHeader;
end;

procedure TPlayerGestion.EnterTimer;
begin

    if FEnterTimerCount = 0 then begin
       // il est sous entendu que l'on entre dans le timer uniquement
       // si il n'est pas vérouillé
       FInTimer := true;
    end;
    Inc(FEnterTimerCount);
end;

procedure TPlayerGestion.ExitTimer;
begin
    Dec(FEnterTimerCount);

    if FEnterTimerCount = 0 then begin
       if FLockTimerCount = 0 then begin
          // déverouille
          FInTimer := false;
       end;
    end;
end;

function TPlayerGestion.LockTimer: boolean;
begin
    if FInTimer then begin
       // on ne peut pas locker si on est deja dans le timer
       Result := false;
       exit;
    end;
    Result := true;

    if FLockTimerCount = 0 then begin
       // fait comme si on était dans le timer (pour empêcher son exécution)
       FInTimer := true;
    end;
    Inc(FLockTimerCount);
end;

procedure TPlayerGestion.UnlockTimer;
begin
    Dec(FLockTimerCount);
    if FLockTimerCount = 0 then begin
       // autorise à nouveau l'execution du timer
       FInTimer := false;
       FLockTimerCount := 0;
    end;

end;



function TPlayerGestion.GetRobotCanDoSomething: boolean;
begin
    Result := GetRobotIsLogged;
    if NoT(Result) then begin
       // pas loggé
       exit;
    end;

    Result := false;

    if FsockHTTP.State <> httpReady then begin
       // socket pas prêt
       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       // un job est en cours
       exit;
    end;

    Result := true;


end;

function TPlayerGestion.GetRobotIsLogged: boolean;
begin
    Result := false;

    if FMustReloginDetected then begin
       // on doit se relogger, on est alors plus loggé
       exit;
    end;

    if FSessionId = '' then begin
       // pas de session id, donc pas loggé
       exit;
    end;

    Result := true;

end;


function TPlayerGestion.myGETorPOST_InTamponX(URL, PostData: string; sckHttp: THttpCli): string;
label lAfficheHeader;
var xURLRedir: string;
begin

    if FMustReloginDetected then begin
       // doit se relogger
       if NoT(FInLogin) then begin
          // on n'est pas en train de se relogger, donc ignore la page web
          Result := mcDL_MUST_RELOGIN;
          exit;
       end;
    end;

    try
       if Conf.NavGZipEncoding then begin
          Result := gzhttpGETorPOST_InTamponX(URL, PostData, sckHttp);
       end else begin
          Result := httpGETorPOST_InTamponX(URL, PostData, sckHttp);
       end;

       if Result <> modDL_ERREUR_DL_STR then begin

          if length(Result) < CNT_MIN_PAGESIZEFILE_FOR_SESSIONEXP_CHECK then begin
             // parfois la page est trop  petite car on se connecte avec un proxy bidon

             if mpcPageWebIsSessionExpireDBProblem(Result) then begin
                Result := mcDL_MUST_RELOGIN;

                 {$IFDEF DEBUG}
                     DoDebug('Download -> Detection d''expiration de session du jeu (doit se relogger)');
                 {$ENDIF}

                // active le flag
                FMustReloginDetected := true;

                if Conf.AutoReloginEnable then begin
                   // gestionnaire d'auto relogin par défaut
                   FNextDateToRelog := DateTimeToUnix(Now) + Conf.AutoReloginDelay + Random(Conf.AutoReloginDelayAjoutRandom);

                    {$IFDEF DEBUG}
                        DoDebug('Download -> Detection d''expiration de session du jeu (doit se relogger) (AutoRelogin activé: ' + IntToStr(FNextDateToRelog) + ')');
                    {$ENDIF}

                   if FAutoReloginLastDate > 800 then begin

                      if FNextDateToRelog < (FAutoReloginLastDate + Conf.AutoReloginMinInterval) then begin
                         // le robot va se relogger deux fois en trop peu de temps
                         // on augmente  le délai
                         FNextDateToRelog := FAutoReloginLastDate + Conf.AutoReloginMinInterval;

                          {$IFDEF DEBUG}
                              DoDebug('Download -> Date d''auto relogin modifiée pour éviter de se logger deux fois trop rapidement (' + IntToStr(FNextDateToRelog) + ')');
                          {$ENDIF}
                      end;
                   end;


                end else begin
                   FNextDateToRelog := 0;

                    {$IFDEF DEBUG}
                        DoDebug('Download -> Detection d''expiration de session du jeu (doit se relogger) (AutoRelogin non activé)');
                    {$ENDIF}
                end;


             end else begin
                // page trop petite mais mpcPageWebIsSessionExpireDBProblem n'a pas identifié de déconnexion
                // parfois, le serveur lag, et il affiche alors une page totalement vide
                if length(Result) < 2 then begin
                    // la page est vraiment petite
                    {$IFDEF DEBUG}
                        DoDebug('Download -> Page trop petite - StatusCode: ' + IntToStr(sckHttp.StatusCode));
                    {$ENDIF}

                    if (sckHttp.StatusCode >= 400) or (sckHttp.StatusCode < 300) then begin
                       // lors de relocation (code 302 lors du calcul des ressources), la page
                       // est vraiment vide et ce n'est pas une erreur

                       // déclenche une erreur de socket, mais en réalité c'est une erreur du serveur
                       // car la connexion est "bonne"
                       // il faut donc faire attention à la gestion de cette erreur
                       Result := modDL_ERREUR_DL_STR;

                       goto lAfficheHeader;

                    end else if sckHttp.StatusCode = 302 then begin
                       {$IFDEF DEBUG}
                           if FsockHTTP = sckHttp  then begin
                              // on ne debug que le socket local
                              // sinon la redirection du tunnel sera affichée

                              xURLRedir := mcsExtractLocation(sckHttp.RcvdHeader);
                              DoDebug('Download -> Redirection détectée vers: ' + xURLRedir);

                              if xURLRedir = '' then begin
                                 // hummm
                                 DoDebug('Header:');
                                 DoDebugStrings(sckHttp.RcvdHeader);
                              end;
                           end else begin
                              DoDebug('Redirection: ok');
                           end;

                       {$ENDIF}


                       // Ne plus afficher l'header sinon l'url du tunnel est repérable
                       //goto lAfficheHeader;



                    end else if (sckHttp.StatusCode > 0) then begin
lAfficheHeader:
                       // affiche l'header
                       {$IFDEF DEBUG}
                          //DoDebug('Header:');
                          //DoDebugStrings(sckHttp.RcvdHeader);
                          DoDebug('----');
                       {$ENDIF}
                    end;


                end;


             end;

          end else begin
             // cette erreur se produit quand on change l'ip ou autre et qu'on nous signale
             // que la sessions n'est plus valide:
(*  <html><head><title>Ogame</title>
<link rel="stylesheet" type="text/css" href="formate.css">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head><body text=#00FFFF backcolor=#00ff00><center><b><font color="#FF0000" size="+1">
Erreur</font></b><br>Votre session n\'est pas valable. Ceci peut avoir différentes raisons :<br><ol><li>
Vous vous êtes loggé plusieurs fois dans le même compte</li><li>Vous n'êtes plus en ligne avec la même adresse
IP que lors de votre dernier login (par ex. si la connexion a été interrompue)</li></ol><br>Veuillez vous relogger :
<a href="http://ogame.fr/" target=_top>Login</a><br><br></center></body></html>Vous jouez avec une autre IP que lors
de votre dernier login.<br> Ceci peut être provoqué par l'utilisation du navigateur AOL.<br>Prière de désactiver
la vérification IP dans les options ou d'utiliser un autre navigateur.
             *)
             

          end;

       end else begin
          // erreur de download
          // géré ici le nombre d'erreur de socket pour ensuite lancer la procédure
          // de detection de perte de connection
          
       end;

    except
       Result := modDL_ERREUR_DL_STR;
    end;
    
end;


procedure TPlayerGestion.Clear(bDelFichierSave: boolean);
var MaxSleep: longword;
begin
        DoDebug('Player internal Clear');

        FRemoteURLGameDir := '';
        FSessionId := '';



        
        // Planete sélectionnée dans la liste
        FCurrentPlanete := nil;


        // Dernière page web downloadé, peut être à nil
        //FLastPageWebDL := nil;
        FParsingPages.Initialisation;


        if bDelFichierSave then begin
           // Fichier de sauvegarde
           FFichier := '';

           // Liste des planètes
           // ATTENTION: on perd alors la liste des éléments à construire...
           FPlaneteList.Clear;
        end;


        FDateMenuLoad    := 0;
        FDateMenuNbError := 0;

        FCookies.Clear;

        if FInLogin then begin
           {$IFDEF DEBUG}
               DoDebug('Clear - FInLogin = true (remit à False)');
           {$ENDIF}
           FInLogin := false;
        end;


        if FsockHTTP.State <> httpReady then begin
           FsockHTTP.Abort;
           {$IFDEF DEBUG}
               DoDebug('Clear - sockHTTP.State <> httpReady (abort)');
           {$ENDIF}

           DoSleep(30);

           MaxSleep := GetTickCount + 5000;

           while FsockHTTP.State <> httpReady do begin
              DoSleep(50);

              if GetTickCount > MaxSleep then begin
                 {$IFDEF DEBUG}
                     DoDebug('Clear - Socket non prêt...');
                 {$ENDIF}
                 break;
              end;
           end;


        end;



        //
        // auto relogin
        //

        FMustReloginDetected := false;
        FNextDateToRelog     := 0;
        

        FAutoReloginLastDate        := 0;




        FMaxFlotteSlot := 1;

end;



(*
function TPlayerGestion.GetLastTypeClassDL: integer;
begin

    if FLastPageWebDL = nil then begin
       Result := -1;
       exit;
    end;

    Result := FLastPageWebDL.ClassTypeParsing;

end;
*)

procedure TPlayerGestion.DoStatus(const Msg: string);
begin

end;

procedure TPlayerGestion.DoStatusGalaxie(const Msg: string);
begin
    if Assigned(FStatusGalaxieScan) then
       FStatusGalaxieScan(Msg);

end;

procedure TPlayerGestion.DoStatusStats(const Msg: string);
begin
    if Assigned(FStatusStatsScan) then
       FStatusStatsScan(Msg);

end;

procedure TPlayerGestion.SetNewDebugProc(Value: TsfcProcStatus);
begin
    FDebugProc := Value;

        // Pour pouvoir se logger
        FParserGetLogIn.DebugProc := Value;

        // pour les stats
        //FParserStats.DebugProc := Value;


        // pour la galaxie
        //FParserGalaxie.DebugProc := Value;


        // pour les flottes
        //FParserFlotte1Vaisseaux.DebugProc := Value;
        //FParserFlotte2Destination.DebugProc := Value;
        //FParserFlotte3OrdreRessources.DebugProc := Value;
        //FParserFlotte4Confirmation.DebugProc := Value;

        // Pour les messages
        //FParserMessagesList.DebugProc := Value;

        // Pour connaitre la page de redirection, bien que
        // ce soit toujours la même, cela permet de savoir
        // surtout si le login s'est bien effectué
        //FParserAfterPostLogin.DebugProc := Value;

        // Après avoir été redirigé, on tombe sur une frame
        // qui sépare l'écran en deux, le menu à gauche, et
        // le reste à droite.
        //FParserFrame.DebugProc := Value;


        {$IFDEF DEBUG_PARSING}
            FParsingPages.DebugProc := Value;
        {$ENDIF}



        // Pour la page de ressources
        //FParserRessource.DebugProc := Value;

        // Pour la page d'apperçu
        //FParserApercu.DebugProc := Value;

        // Pour la page batiment, recherche, station spatial, défense
        //FParserElement.DebugProc := Value;


end;

procedure TPlayerGestion.Lock;
begin
    EnterCriticalSection(ReadWriteCS);
end;

procedure TPlayerGestion.Unlock;
begin
    LeaveCriticalSection(ReadWriteCS);
end;


function TPlayerGestion.DownloadMiscFiles(list: TStrings): integer;
label lRedo;
var sPageWeb, sURL: string;

    i: integer;

    daSocket: THttpCli;
begin

     if (list = nil) or (list.Count < 1) then begin
        Result := 1;
        exit;
     end;

     daSocket := THttpCli.Create(nil);
     suCopySocketHttpInfos(daSocket, FsockHTTP);

     Result := -1;

     {$IFDEF DEBUG}
        //DoDebug('DownloadMiscFiles - Début');
     {$ENDIF}





     // La référence est le menu
     daSocket.Reference := FParsingPages.LastPageURL;
     daSocket.Cookie    := '';

     for i := 0 to list.Count - 1 do begin
         sURL := list.Strings[i];
         if pos('http://', sURL) <> 1 then begin
            // erreur
            {$IFDEF DEBUG}
                //DoDebug('DownloadMiscFiles - Erreur: ' + sURL);
                DoDebug('DownloadMiscFiles - Erreur');
            {$ENDIF}

         end else begin
            {$IFDEF DEBUG}
                //DoDebug('DownloadMiscFiles - Downloading: ' + sURL);
            {$ENDIF}
            sPageWeb := myGETorPOST_InTamponX(sURL, '', daSocket);
         end;

     end;

     daSocket.Free;
     daSocket := nil;

end;

function TPlayerGestion.DownloadMenuLeft: integer;
label lRedo;
var sHTTP, sPageWeb: string;
    iRedo: integer;

    daSocket: THttpCli;
begin
(*

     // Le menu à gauche peut se télécharger à n'importe quel moment
     // il se peut qu'une action soit déjà en cours
     // ou même qu'un enchainement d'action soit programmé
     // On doit alors obligatoirement utilisé un autre socket
     // pour télécharger ce menu

     daSocket := THttpCli.Create(nil);

     suCopySocketHttpInfos(daSocket, FsockHTTP);

     Result := -1;

     {$IFDEF DEBUG}
        DoDebug('DownloadMenuLeft - Début');
     {$ENDIF}



     //////////////////////////////////////////////////////////////////////////
     // Télécharge la frame de gauche (le menu)
     {$IFDEF DEBUG}
        DoDebug('DownloadMenuLeft - Télécharge le menu à gauche: ' + FParserMenu.URLOfThisFrame);
     {$ENDIF}

     daSocket.Reference := FParserFrame.URLOfThisFrame;
     daSocket.Cookie    := FCookies.GetCookieData;

    iRedo := 0;
lRedo:
    Inc(iRedo);


     sPageWeb := myGETorPOST_InTamponX(FParserMenu.URLOfThisFrame, '', daSocket);
 //    sPageWeb := gzhttpGETorPOST_InTamponX(FParserMenu.URLOfThisFrame, '', FsockHTTP);

     if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
          DoDebug('DownloadMenuLeft - Erreur dl - Page non téléchargée');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SOCKET;

          daSocket.Free;
          daSocket := nil;
          exit;
       end;

       goto lRedo;

    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
        // doit se reloger
        Result := CNT_ERROR_MUST_RELOGIN;
        daSocket.Free;
        daSocket := nil;
        exit;



     end else if (FParserMenu.ParseBuffer(sPageWeb) = false) then begin
        {$IFDEF DEBUG}
           DoDebug('DownloadMenuLeft - FParserMenu Echec');
           DoDebug(sPageWeb);
           DoDebug('DownloadMenuLeft - FParserMenu Echec');
        {$ENDIF}

        FParserMenu.RestaureBackup;


        // erreur fatale car la page semble bonne (avec sa taille)
        // mais le parsing a échoué
        Result := CNT_ERROR_PARSING;

        daSocket.Free;
        daSocket := nil;

        if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
           Result := CNT_ERROR_MUST_RELOGIN;
        end;
        exit;
     end;

     // Gère les cookies
     FCookies.ParseHeader(daSocket.RcvdHeader);

     // Définit le lien complet pour faciliter le téléchargement des pages
     FParserMenu.SetFullURLFromBase(FParserMenu.URLOfThisFrame);
     FDateMenuLoad := DateTimeToUnix(Now);

     Result := CNT_SUCCESS;

     daSocket.Free;
     daSocket := nil;

     {$IFDEF DEBUG}
        DoDebug('DownloadMenuLeft - Succès');
     {$ENDIF}
*)

end;


function TPlayerGestion.CanEnterInTimer: boolean;
begin
    Result := false;

    if FInTimer then begin
       {$IFDEF DEBUGTIMER}
           DoDebug('xcOnTimer - Déjà dans le timer');
       {$ENDIF}
       exit;
    end;

    if FInLogin then begin
       {$IFDEF DEBUGTIMER}
           DoDebug('xcOnTimer - Le login est en cours...');
       {$ENDIF}
       exit;
    end;


    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUGTIMER}
           DoDebug('xcOnTimer - Socket pas pret');
       {$ENDIF}
       exit;
    end;


    if FJobOccupation <> jobpAucun then begin
       // Réessaye plus tard
       {$IFDEF DEBUGTIMER}
           DoDebug('xcOnTimer - Job en cours, ressayera plus tard');
       {$ENDIF}
       exit;
    end;



(*
    if (FDateMenuLoad < 100) then begin
       // On n'a jamais été loggé
       {$IFDEF DEBUG}
           DoDebug('xcOnTimer - Le login n''a jamais ete effectue');
       {$ENDIF}
       exit;
    end;
*)

    Result := true;

end;

procedure TPlayerGestion.OnTimer;
label lParsingMenuDoMustRelogin, lReloginSuccess;
var i: integer;
begin



    //
    // S'occupe de l'auto relogin
    //

    if FMustReloginDetected then begin
       // on doit se relogger

       if (LastCurrDate > FNextDateToRelog) and (FNextDateToRelog > 100) then begin
          // on peut se relogger
          i := ProceedLogin;

          if i < 1 then begin
             // login échoué

             {$IFDEF DEBUG}
                 DoDebug('xcOnTimer - Auto Relogin échoué (Resultat: ' + IntToStr(i) + ')');
             {$ENDIF}

             if LoginUseLocalWebPage then begin
                // on a utilisé une page locale en plus, on ne peut rien faire d'autre...
                   {$IFDEF DEBUG}
                       DoDebug('xcOnTimer - Auto Relogin: Page en cache déjà utilisée');
                   {$ENDIF}

             end else begin
                // sinon essaye avec le cache
                if DirectLoginPreloadCachePage then begin
                   // cache chargé
                   LoginUseLocalWebPage := true;

                   {$IFDEF DEBUG}
                       DoDebug('xcOnTimer - Auto Relogin: Réessaye avec la page d''accueil en cache...');
                   {$ENDIF}



                   i := ProceedLogin;

                   LoginUseLocalWebPage := false;

                   if i < 1 then begin
                      // toujours une erreur...

                   end else begin
                      // sinon on a réussi
                      goto lReloginSuccess;
                   end;

                   {$IFDEF DEBUG}
                       DoDebug('xcOnTimer - Auto Relogin: échoué (Resultat: ' + IntToStr(i) + ')');
                   {$ENDIF}


                end else begin
                   {$IFDEF DEBUG}
                       DoDebug('xcOnTimer - Auto Relogin: Echec de chargement de la page d''accueil en cache...');
                   {$ENDIF}

                end;

             end;


             FNextDateToRelog := LastCurrDate + 360;
             exit;
          end;

lReloginSuccess:

          // login réussi, on continue dans le timer
          FAutoReloginLastDate := LastCurrDate;

          {$IFDEF DEBUG}
             DoDebug(_('xcOnTimer - Auto Relogin réussi'));
          {$ENDIF}

       end else begin
          // sinon on attend
          exit;
       end;
    end;


    //
    // S'occupe du menu à gauche
    //
(* 0.77: Plus de menu à gauche indépendant

    if (LastCurrDate -  FDateMenuLoad > 1799) then begin
       // Recharge la page du menu

       {$IFDEF DEBUG}
           if FParserMenu.DelayRefresh > 0 then begin
              DoDebug('xcOnTimer - Téléchargement du menu à gauche');
           end else begin
              DoDebug('xcOnTimer - Téléchargement du menu à gauche (x)');
           end;

       {$ENDIF}

       if FParserMenu.DelayRefresh > 0 then begin
          i := DownloadMenuLeft;

       end else begin
          // plus besoin de télécharger le menu à gauche
          i := 1;
       end;

       if i > 0 then begin
          // réussi
          {$IFDEF DEBUG}
              DoDebug('xcOnTimer - Téléchargement du menu à gauche réussi');
          {$ENDIF}

          // met à jour la date
          FDateMenuLoad := DateTimeToUnix(Now);
          LastCurrDate  := FDateMenuLoad;

       end else if i = CNT_ERROR_MUST_RELOGIN then begin
          // doit obligatoire se relogger
          {$IFDEF DEBUG}
              DoDebug('xcOnTimer - Téléchargement du menu à gauche - Echec -> Doit se reloger');
          {$ENDIF}


          // a t on l'auto relogin d'activer ?
          if FAlerteAttaqueAutoReloginEnable then begin
             // il l'est pour l'alerte d'attaque, donc on s'auto relog

          end;
     

          FDateMenuLoad := 200;
          exit;


       end else if i = CNT_ERROR_PARSING then begin
          // Erreur de parsing
          // Erreur grave du peut-être à une mise à jour du jeu
          // On ne fait PAS d'auto relogin


          {$IFDEF DEBUG}
              DoDebug('xcOnTimer - Téléchargement du menu à gauche - Erreur FATALE -> Echec de parsing');
          {$ENDIF}

          // ici on le met bien à 0 pour éviter l'exécution de OnTimer
          FDateMenuLoad := 0;
          exit;

       end else if i = CNT_ERROR_SOCKET then begin
          // erreur de socket...
          {$IFDEF DEBUG}
              DoDebug('xcOnTimer - Téléchargement du menu à gauche - Erreur de socket -> Connexion perdue ou mise à jour des stats en cours ?');
          {$ENDIF}

          // on réessayera dans 2 minutes
          FDateMenuLoad := FDateMenuLoad + 120;


       end else begin
          // Doit se relogger...
          // Met quand même à jour la date de téléchargement pour pas qu'à chaque
          // seconde l'on retélécharge la page
      //    FDateMenuLoad := DateTimeToUnix(Now);

          {$IFDEF DEBUG}
              DoDebug('xcOnTimer - Téléchargement du menu à gauche - Echec -> Devrait se reloguer ?');
          {$ENDIF}

          // attention, on met ici la date à 200 pour pas que le message
          //  DoDebug('xcOnTimer - Le login n''a jamais ete effectue');
          // soit appellé à chaque fois
          Inc(FDateMenuNbError);

          if FDateMenuNbError > 3 then begin
             // ok, il y a un problème
             FDateMenuLoad := 200;
             exit;
          end;

       end;

    end;
*)



end;


function TPlayerGestion.ProceedUpdateEverythingOnEveryPlanet(bForceAppercu: boolean = false): integer;
var myPlanetCollect: TCollectionLinkOtherPlanete;
    i: integer;
    lr: PLinkOtherPlanete;

    CurrPlanete: TPlaneteInfo;
begin

     Result := -33;
     
     if FInLogin then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEverythingOnEveryPlanet - Impossible à effectuer car login en cours');
        {$ENDIF}
        exit;
     end;

     if FsockHTTP.State <> httpReady then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEverythingOnEveryPlanet - Impossible à effectuer car sockHTTP non prêt');
        {$ENDIF}
        exit;
     end;

     if FJobOccupation <> jobpAucun then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEverythingOnEveryPlanet - Un autre job est déjà en cours d''exécution');
        {$ENDIF}

        exit;
     end;

     {$IFDEF DEBUG}
        DoDebug('ProceedUpdateEverythingOnEveryPlanet - Start');
     {$ENDIF}


     // Si le login a été effectué, on a au moins une planete
     if (FCurrentPlanete = nil) or (cParsing.LastPage = nil)  then begin
        // Il y a toujours au moins une planète en cours
        // si le login a été effectué
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEverythingOnEveryPlanet - FCurrentPlanete ou FLastPageWebDL à nil');
        {$ENDIF}

        Result := -2;
        exit;

     end else if GetRobotCanDoSomething = false then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEverythingOnEveryPlanet - GetRobotCanDoSomething = false');
        {$ENDIF}

        Result := -29;
        exit;
     end;



     Result := -1;



     if cParsing.pHeader.AutrePlanete.Count = 0 then begin
        // Ok, une seule planète

        if FPlaneteList.Count > 1 then begin
           // il est censé y avoir qu'une seule planete...
           // mais le robot en connait plusieurs
           // cela peut etre du à la destruction de planetes
           FPlaneteList.PrepareUpdate;

           CurrPlanete := FPlaneteList.GetPlanete(cParsing.pHeader.Planete);

           if CurrPlanete <> FCurrentPlanete then begin
              // problème...
              {$IFDEF DEBUG}
                 DoDebug('ProceedUpdateEverythingOnEveryPlanet - CurrPlanete <> FCurrentPlanete');
              {$ENDIF}

           end;

           FCurrentPlanete := CurrPlanete;
           FCurrentPlanete.HaveNOTBeenUpdated := false;

           FPlaneteList.FinalizeUpdate;
        end;

        Result := ProceedUpdateAllElements;

        if Result < 0 then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateAllElements, 1 planète');
           {$ENDIF}

           exit;
        end;

        Result := ProceedUpdateRessource(true, false);
        if Result < 0 then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateRessource, 1 planète');
           {$ENDIF}

           exit;
        end;


        // Si il n'y a qu'une planète, c'est la planète mère, et l'on ne devrai
        // normalement pas mettre à jour la page d'apperçu, car elle a été
        // téléchargée lors du login, cependant, il se peut que le programme
        // soit lancé depuis longtemps
        if FCurrentPlanete.pShouldUpdateAppercu then begin
           Result := ProceedUpdateApercu;
           if Result < 0 then begin
              {$IFDEF DEBUG}
                  DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateApercu - 1 planète');
              {$ENDIF}
              exit;
           end;

        end;

        
     end else if cParsing.pHeader.AutrePlanete.Count > 0 then begin
        // Lors du téléchargement des pages, FLastPageWebDL va être modifer,
        // mais surtout le contenu de AutrePlanete aussi
        // On sauvegarde donc la liste des planètes
        
        myPlanetCollect := TCollectionLinkOtherPlanete.Create;

        for i := 0 to cParsing.pHeader.AutrePlanete.Count - 1 do begin
            // extrait un pointeur
            lr := cParsing.pHeader.AutrePlanete.Items[i];


            // sauvegarde le contenu du pointeur
            myPlanetCollect.Add(lr^);
        end;

        // Prépare la mise à jour pour effacer les planètes qui ont été détruite
        FPlaneteList.PrepareUpdate;

        // La planète actuelle n'existe pas dans cHeader.AutrePlanete
        // On la met donc à jour maintenant
        FCurrentPlanete.HaveNOTBeenUpdated := false;

        // Maintenant on peut mettre à jour la planète actuelle
        Result := ProceedUpdateAllElements;
        if Result < 0 then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateAllElements, planète en cours - plusieurs planètes');
           {$ENDIF}
           exit;
        end;
        Result := ProceedUpdateRessource(true, false);
        if Result < 0 then begin
           {$IFDEF DEBUG}
               DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateRessource, planète en cours - plusieurs planètes');
           {$ENDIF}
           exit;
        end;
        
        // Puis les autres planète
        for i := 0 to myPlanetCollect.Count - 1 do begin
           lr := myPlanetCollect.Items[i];

           DoSleep(900);

           Result := ChangePlanete(lr.Location);
           if Result < 0 then begin
              {$IFDEF DEBUG}
                 DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec de changement de planète');
              {$ENDIF}

              exit;
           end;

           DoSleep(870);

           Result := ProceedUpdateAllElements;
           if Result < 0 then begin
              {$IFDEF DEBUG}
                 DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateAllElements - Item: ' + IntToStr(i));
              {$ENDIF}

              exit;
           end;

           DoSleep(780);

           Result := ProceedUpdateRessource(true, false);
           if Result < 0 then begin
              {$IFDEF DEBUG}
                  DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateRessource - Item: ' + IntToStr(i));
              {$ENDIF}

              exit;
           end;

           if bForceAppercu or (FCurrentPlanete.pShouldUpdateAppercu) then begin
              Result := ProceedUpdateApercu;
              if Result < 0 then begin
                 {$IFDEF DEBUG}
                    DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateApercu - Item: ' + IntToStr(i));
                 {$ENDIF}
                 exit;
              end;

           end;

           // Indique que la planète a été mise à jour
           FCurrentPlanete.HaveNOTBeenUpdated := false;

        end;


        i := FPlaneteList.FinalizeUpdate;

        if i > 0 then begin
           {$IFDEF DEBUG}
              DoDebug('Planètes détruites: ' + IntToStr(i));
           {$ENDIF}

        end;

        Result := 1;
        
        // Libère la liste
        myPlanetCollect.Free;

     end else begin
        // Impossible car sinon FCurrentPlanete = nil et
        // FLastPageWebDL aussi
        Result := -3;

     end;

end;




function TPlayerGestion.ProceedUpdateEveryBatimentOnEveryPlanet: integer;
var myPlanetCollect: TCollectionLinkOtherPlanete;
    i: integer;
    lr: PLinkOtherPlanete;

begin

     Result := -33;

     if FInLogin then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - Impossible a effectué car login en cours');
        {$ENDIF}
        exit;
     end;

     if FsockHTTP.State <> httpReady then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - Impossible a effectué car sockHTTP non prêt');
        {$ENDIF}
        exit;
     end;

     if FJobOccupation <> jobpAucun then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - Un autre job est déjà en cours d''exécution');
        {$ENDIF}

        exit;
     end;

     {$IFDEF DEBUG}
        DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - Start');
     {$ENDIF}


     // Si le login a été effectué, on a au moins une planete
     if (FCurrentPlanete = nil) or (cParsing.LastPage = nil) then begin
        // Il y a toujours au moins une planète en cours
        // si le login a été effectué
        {$IFDEF DEBUG}
           DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - FCurrentPlanete ou FLastPageWebDL à nil');
        {$ENDIF}

        Result := -2;
        exit;
     end;

     Result := -1;



     if cParsing.pHeader.AutrePlanete.Count = 0 then begin
        // Ok, une seule planète
        Result := ProceedUpdateElement(mliBatiments);

        if Result < 0 then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedUpdateEveryBatimentOnEveryPlanet - Echec ProceedUpdateAllElements, 1 planète');
           {$ENDIF}

           exit;
        end;


        // Si il n'y a qu'une planète, c'est la planète mère, et l'on ne devrai
        // normalement pas mettre à jour la page d'apperçu, car elle a été
        // téléchargée lors du login, cependant, il se peut que le programme
        // soit lancé depuis longtemps
        if FCurrentPlanete.pShouldUpdateAppercu then begin
           Result := ProceedUpdateApercu;
           if Result < 0 then begin
              {$IFDEF DEBUG}
                  DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateApercu - 1 planète');
              {$ENDIF}
              exit;
           end;

        end;


     end else if cParsing.pHeader.AutrePlanete.Count > 0 then begin
        // Lors du téléchargement des pages, FLastPageWebDL va être modifer,
        // mais surtout le contenu de AutrePlanete aussi
        // On sauvegarde donc la liste des planètes
        
        myPlanetCollect := TCollectionLinkOtherPlanete.Create;

        for i := 0 to cParsing.pHeader.AutrePlanete.Count - 1 do begin
            // extrait un pointeur
            lr := cParsing.pHeader.AutrePlanete.Items[i];


            // sauvegarde le contenu du pointeur
            myPlanetCollect.Add(lr^);
        end;

        // Prépare la mise à jour pour effacer les planètes qui ont été détruite
        FPlaneteList.PrepareUpdate;

        // La planète actuelle n'existe pas dans cHeader.AutrePlanete
        // On la met donc à jour maintenant
        FCurrentPlanete.HaveNOTBeenUpdated := false;

        // Maintenant on peut mettre à jour la planète actuelle
        Result := ProceedUpdateElement(mliBatiments);
        if Result < 0 then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateAllElements, planète en cours - plusieurs planètes');
           {$ENDIF}
           exit;
        end;

        // Puis les autres planète
        for i := 0 to myPlanetCollect.Count - 1 do begin
           lr := myPlanetCollect.Items[i];

           DoSleep(900);

           Result := ChangePlanete(lr.Location);
           if Result < 0 then begin
              {$IFDEF DEBUG}
                 DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec de changement de planète');
              {$ENDIF}

              exit;
           end;

           DoSleep(950);

           Result := ProceedUpdateElement(mliBatiments);
           if Result < 0 then begin
              {$IFDEF DEBUG}
                 DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateAllElements - Item: ' + IntToStr(i));
              {$ENDIF}

              exit;
           end;

           DoSleep(750);


           if (FCurrentPlanete.pShouldUpdateAppercu) then begin
              Result := ProceedUpdateApercu;
              if Result < 0 then begin
                 {$IFDEF DEBUG}
                    DoDebug('ProceedUpdateEverythingOnEveryPlanet - Echec ProceedUpdateApercu - Item: ' + IntToStr(i));
                 {$ENDIF}
                 exit;
              end;

           end;

           // Indique que la planète a été mise à jour
           FCurrentPlanete.HaveNOTBeenUpdated := false;
        end;


        i := FPlaneteList.FinalizeUpdate;

        if i > 0 then begin
           {$IFDEF DEBUG}
              DoDebug('Planètes détruites: ' + IntToStr(i));
           {$ENDIF}

        end;

        Result := 1;

        // Libère la liste
        myPlanetCollect.Free;

     end else begin
        // Impossible car sinon FCurrentPlanete = nil et
        // FLastPageWebDL aussi
        Result := -3;

     end;

end;




function TPlayerGestion.ChangePlanete(Nouvelle: TPlanetLocation; bForceAEtreCertainDetreDessus: boolean = false): integer;
label lRedo, lRedoLink, lblDoChangement, lRedir;
var p: PLinkOtherPlanete;
    sPageWeb, sLinkPageBackup: string;
    cPlanete: TPlaneteInfo;
    iRedo, j: integer;

    sURLRedir, sURLtoDL: string;
    sRedirState: TRessourceRedirState;
begin


    {$IFDEF DEBUG}
        DoDebug('ChangePlanete - Nouvelle: ' + mbtPlanetLocationToStr(Nouvelle));
    {$ENDIF}

    if (cParsing.LastPage = nil) or (Assigned(cParsing.LastPageParsingMethod) = false) then begin
       Result := CNT_ERROR_FATAL;
       {$IFDEF DEBUG}
           DoDebug('ChangePlanete - FLastPageWebDL = nil (ou method)');
       {$ENDIF}
       exit;
    end;




    // on revient ici car il se peut qu'en fait le changement soit inutile
    iRedo := 0;
lRedoLink:
    Inc(iRedo);

    if CompareLocation(cParsing.pHeader.Planete, Nouvelle) = false then begin
       // Ok, c'est bien un changement de planète
lblDoChangement:
       Result := CNT_ERROR_FATAL;



       p := cParsing.pHeader.AutrePlanete.Get_Pointeur(Nouvelle);

       if p = nil then begin

         // la dernière page a peut-être mal été téléchargé
         if cParsing.IsValidPage = false then begin
            // c'est le cas...
           {$IFDEF DEBUG}
              DoDebug('ChangePlanete - La page précédente a mal été téléchargé (header invalide)');
              DoDebug('ChangePlanete -> Telechargement de la page apercu');
           {$ENDIF}

           // on va télécharger simplement la page aperçu.
           j := ProceedUpdateApercu;

           if j < 0 then begin

              if (j = CNT_ERROR_MUST_RELOGIN) then begin
                 {$IFDEF DEBUG}
                    DoDebug('ChangePlanete - Doit se relogger');
                 {$ENDIF}
                 Result := j;
                 exit;

              end else if (j = CNT_ERROR_SOCKET) then begin
                 // théoriquement les essais multiples ont déjà été réalisé
                 // dans la fonction de téléchargement de la page apercu
                 {$IFDEF DEBUG}
                    DoDebug('ChangePlanete - Socket error');
                 {$ENDIF}
                 Result := j;
                 exit;

              end else if j = CNT_ERROR_PARSING then begin
                 // erreur de parsing...
                 Result := j;
                 exit;
              end;

              Result := j;
              exit;


           end else begin
              // la page a bien été téléchargé
              if iRedo > 2 then begin
                 // bizarre
                 {$IFDEF DEBUG}
                    DoDebug('ChangePlanete - Trop d''essai pour obtenir un lien de changement valide');
                 {$ENDIF}
                 exit;
              end;
              goto lRedoLink;
           end;


         end else begin
           {$IFDEF DEBUG}
              DoDebug('ChangePlanete - Impossible de trouver le lien de changement de planète (IsValidPage: ' + iif(cParsing.IsValidPage, 'yes', 'no') + ')');
              DoDebug('ChangePlanete - Nombre de planètes connues: ' + IntToStr(cParsing.pHeader.AutrePlanete.Count));
           {$ENDIF}
           exit;
         end;


       end;


       if p.Lien = '' then begin
          {$IFDEF DEBUG}
             DoDebug('ChangePlanete - Le lien trouvé est vide');
          {$ENDIF}

          exit;
       end;


       if lowercase(copy(p.Lien, 1, 4)) <> 'http' then begin
           {$IFDEF DEBUG}
              DoDebug('ChangePlanete - Oublie de définition de l''url de la page (1)');
           {$ENDIF}

           exit;
       end;


       // On télécharge la page web
       // celle-ci provient suite à un clique de la même page
       FsockHTTP.Reference := cParsing.LastPageURL;

       if length(FsockHTTP.Reference) < 10 then begin
           {$IFDEF DEBUG}
              DoDebug('ChangePlanete - Oubli de définition de l''url de la page (2)');
           {$ENDIF}

           exit;
       end;

       // On n'oublie pas les cookies
       FsockHTTP.Cookie    := FCookies.GetCookieData;

       iRedo := 0;
       sURLtoDL := p.Lien;
lRedo:
       Inc(iRedo);


       // Et on télécharge la page
       {$IFDEF DEBUG}
          DoDebug('ChangePlanete - Téléchargement page de changement de planete: ' + sURLtoDL);
       {$ENDIF}

       sPageWeb := myGETorPOST_InTamponX(sURLtoDL, '', FsockHTTP);

       sLinkPageBackup := sURLtoDL;




       if (FsockHTTP.StatusCode >= 300) and (FsockHTTP.StatusCode < 400) then begin
          // on est face à une redirection

          if (sRedirState = trrsNeant) and (sRedirState <> trrsHandled) then begin
             sURLRedir := mcsExtractLocation(FsockHTTP.RcvdHeader);
             FCookies.ParseHeader(FsockHTTP.RcvdHeader);

             if sURLRedir = '' then begin
               {$IFDEF DEBUG}
                   DoDebug('ChangePlanete - (x) Lien de redirection non trouvée - StatusCode: ' + IntToStr(FsockHTTP.StatusCode));
               {$ENDIF}
               Result := CNT_ERROR_FATAL;
               exit;
             end;

             sRedirState := trrsHTTP302;
             goto lRedir;

          end else begin
             // double redirection ???
             {$IFDEF DEBUG}
                 DoDebug('ChangePlanete - Loop Erreur');
             {$ENDIF}

          end;

       end;




   //    DebugWebPage(sPageWeb);

       // On analyse la page web, même si l'on ne sait pas ce qu'elle contient
       // car on veut extraire l'header
       if sPageWeb = modDL_ERREUR_DL_STR then begin
          {$IFDEF DEBUG}
              DoDebug('ChangePlanete - Erreur dl - Page non téléchargée');
          {$ENDIF}


          if iRedo > 4 then begin
             Result := CNT_ERROR_SOCKET;
             exit;
          end;
          Sleep(1000);
          goto lRedo;


       end else if sPageWeb = mcDL_MUST_RELOGIN then begin
          // doit se relogger
          Result := CNT_ERROR_MUST_RELOGIN;
          exit;



       end else if cParsing.LastPageParsingMethod(sPageWeb) = false then begin



           if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
              Result := CNT_ERROR_MUST_RELOGIN;

           end else begin
              Result := CNT_ERROR_PARSING;
           end;




          if FParsingPages.IsValidPage = false then begin
             // erreur de socket

             if (sRedirState = trrsNeant) and (sRedirState <> trrsHandled) then begin
                // vérifie si ce n'est pas une redirection HTML
                sURLRedir := '';
                sURLRedir := ExtractRedirRessourceURL(sPageWeb);

                if length(sURLRedir) > 5 then begin
                   // c'était une redirection html
                   sRedirState := trrsHTML;
                   goto lRedir;
                end;
             end;

             {$IFDEF DEBUG}
                 DoDebug('ChangePlanete - Page invalide... Taille: ' + IntToStr(length(sPageWeb)));
             {$ENDIF}


             if iRedo > 2 then begin
                Result := CNT_ERROR_PARSING;

                if length(sPageWeb) > 10 then begin
                   {$IFDEF DEBUGFILE_WHEN_ECHEC}
                      DebugWebPage(sPageWeb, CNT_DEBUGFILE_RESSOURCES);
                   {$ENDIF}
                end;
                exit;
             end;

             goto lRedo;

          end;


                {$IFDEF DEBUGFILE_WHEN_ECHEC}
                   DebugWebPage(sPageWeb, CNT_DEBUGFILE_CHANGE_PLANETE);
                {$ENDIF}

           {$IFDEF DEBUG}
               DoDebug('ChangePlanete - Erreur de parsing de la page de changement de planète');
           {$ENDIF}




           exit;
       end;


lRedir:
    if (sRedirState <> trrsNeant) and (sRedirState <> trrsHandled) then begin
       // aucune page ressources n'a été téléchargé

       sRedirState := trrsHandled;

       // définit la nouvelle url
       sURLtoDL  := sHTML_Get_URL_Lien(sLinkPageBackup, sURLRedir);

       iRedo := 0;

       goto lRedo;

    end;




       // Gère les cookies
       FCookies.ParseHeader(FsockHTTP.RcvdHeader);


       // Maintenant extrait le pointeur de la planete
       cPlanete := FPlaneteList.GetPlanete(cParsing.pHeader.Planete);
       if cPlanete = nil then begin
          cPlanete := TPlaneteInfo.Create;
          FPlaneteList.Add(cPlanete);

          
          {$IFDEF DEBUG}
             cPlanete.DebugProc := FDebugProc;
          {$ENDIF}
          {$IFDEF DEBUG}
             DoDebug('ChangePlanete - Ajout de la planète dans la liste');
          {$ENDIF}

       end;



       // Met à jour les données
       cPlanete.FNom                := cParsing.pHeader.PlaneteNom;
       cPlanete.FLocation           := cParsing.pHeader.Planete;
       cPlanete.FLastRessources     := cParsing.pHeader.CurrRessource;
       cPlanete.FLastRessourcesDate := DateTimeToUnix(Now);

       {$IFDEF DEBUG}
           DoDebug('ChangePlanete - Planète mise à jour');
       {$ENDIF}

       cPlanete.SendDebugAllPlanetInfo;

       // Met à jour le pointeur de la planète en cours
       FCurrentPlanete := cPlanete;

       if (FDontDLAppercuPageOnChangePlanet = false) and FCurrentPlanete.pShouldUpdateAppercu then begin
          Result := ProceedUpdateApercu;

       end else begin
          
          cParsing.SetURLOfThisPage(sLinkPageBackup);
          Result := CNT_SUCCESS;

       end;

       
    end else begin

       if bForceAEtreCertainDetreDessus then begin
         {$IFDEF DEBUG}
            DoDebug('ChangePlanete - Planète déjà sélectionnée, mais vérifie qu''elle n''a pas changé par le tunnel');
         {$ENDIF}

         // rien de plus simple, on va télécharger la page aperçu
         if ProceedUpdateApercu < 0 then begin
            Result := -1;

         end else begin
            // la page apercu a été téléchargé
            // on vérifie si elle correspond bien à la planète où l'on veut être
            if CompareLocation(cParsing.pHeader.Planete, Nouvelle) = false then begin
               // ça ne correspond pas
               // il faut effectuer un changement
               goto lblDoChangement;
               
            end else begin
               // ça correspond
               Result := CNT_NO_EFFECT;
            end;
         end;


       end else begin
         {$IFDEF DEBUG}
            DoDebug('ChangePlanete - Planète déjà sélectionnée');
         {$ENDIF}
         Result := CNT_NO_EFFECT;
       end;


    end;
    

end;

(*
function TPlayerGestion.GetLastHeaderClass: TParsingDebutDocumentMineraiAndPlanet;
begin
    if FLastPageWebDL = nil then begin
       Result := nil;
       exit;
    end;

    Result := FLastPageWebDL.cHeader;
end;
*)


function TPlayerGestion.ProceedUpdateAllElements: integer;
begin

    Result := -1;



    if ProceedUpdateElement(mliBatiments) < 0 then begin
        {$IFDEF DEBUG}
            DoDebug('Erreur - ProceedUpdateAllElements - CNT_MENU_BATIMENTS');
        {$ENDIF}

        exit;
    end;

    DoSleep(800);

    if ProceedUpdateElement(mliRecherche) < 0 then begin
        {$IFDEF DEBUG}
            DoDebug('Erreur - ProceedUpdateAllElements - CNT_MENU_RECHERCHES');
        {$ENDIF}

        exit;
    end;

    DoSleep(900);

    if ProceedUpdateElement(mliChantierSpatial) < 0 then begin
        {$IFDEF DEBUG}
            DoDebug('Erreur - ProceedUpdateAllElements - CNT_MENU_CHANTIERSPATIAL');
        {$ENDIF}

        exit;
    end;

    DoSleep(800);

    if ProceedUpdateElement(mliDefense) < 0 then begin
        {$IFDEF DEBUG}
            DoDebug('Erreur - ProceedUpdateAllElements - CNT_MENU_DEFENSE');
        {$ENDIF}

        exit;
    end;

    Result := 1;
end;



procedure TPlayerGestion.SetDebugWebPageDossier(Valeur: string);
begin
    FDebugWebPageDossier := IncludeTrailingPathDelimiter(Valeur);
    ForceDirectories(FDebugWebPageDossier);
end;

{$IFDEF DEBUGFILE_FLAG}
procedure TPlayerGestion.DebugWebPage(Page: string; Titre: string);
var Fichier: string;
    F: TextFile;
begin

    if FDebugWebPageActive = false then exit;

    Fichier := FDebugWebPageDossier + Titre + '.html';
    Fichier := sfcFileGetNextNonExist(Fichier, 4);

    AssignFile(F, Fichier);

    {$I-}
    ReWrite(F);
    {$I+}

    // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
    if NoT(IOResult = 0) then begin
       {$IFDEF DEBUG}
           DoDebug('DebugWebPage - Erreur d''ouverture: ' + Fichier);
       {$ENDIF}

       exit;
    end;

    WriteLn(F, Page);

    CloseFile(F);

end;
{$ENDIF}


procedure TPlayerGestion.SauvegardeRapportCombat(pe: POGMessage; PageWeb: string);
var Fichier: string;
    Tampon: string;
    F: TextFile;
    Planete: TPlanetLocation;
    PlaneteRapport: TPlaneteInfo;

    PlaneteIsOwn: boolean;

    StrPlanete: string;
    StrPertes : string;
    StrDate   : string;
    xPos: integer;
begin

    if DossierRapportCombat = '' then begin
       exit;
    end;
    if DossierRapportCombat[length(DossierRapportCombat)] <> '\' then begin
       exit;
    end;

    // Battle Report [2:361:6] (V:0,A:3000)
    Planete := mpcExtractPlanetLocation(pe.Sujet);
    PlaneteIsOwn := false;

    StrPertes  := 'ABC';
    StrPlanete := 'XYYYZZ';

    if (Planete.Galaxie > 0) and (Planete.SystemSolaire > 0) and (Planete.Position > 0) then begin
       // planète valide
       PlaneteRapport := FPlaneteList.GetPlanete(Planete);

       if PlaneteRapport <> nil then begin
          // la bataille s'est passée sur une planète de l'utilisateur du robot
          PlaneteIsOwn := true;

       end else begin
          // la bataille s'est passée sur une planète ennemie

       end;

       StrPlanete := format('%d-%d-%d', [Planete.Galaxie, Planete.SystemSolaire, Planete.Position]);

       xPos := LastDelimiter('(', pe.Sujet);
       if xPos > 0 then begin
          Tampon := copy(pe.Sujet, xPos + 1, maxint);

          xPos := pos(')', Tampon);
          if xPos > 0 then begin
             System.Delete(Tampon, xPos, maxint);


             // V:0,A:3000
             StrPertes := sfcRemplace(Tampon,    ',', '_');
             StrPertes := sfcRemplace(StrPertes, ':', '-');
          end;
       end;


    end else begin
       // planète invalide

    end;

    if PlaneteIsOwn then begin
       // la bataille s'est passée sur une planète de l'utilisateur du robot
       StrPlanete := '#' + StrPlanete + '#';
    end;

    StrDate := format('%4.4d%2.2d%2.2d', [YearOf(Now), MonthOf(Now), DayOf(Now)]);

    Fichier := format('u%dr%s[%s]_%s.html', [Conf.Univers, StrDate, StrPlanete, StrPertes]);


    Fichier := DossierRapportCombat + Fichier;


    AssignFile(F, Fichier);

    {$I-}
    ReWrite(F);
    {$I+}

    // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
    if NoT(IOResult = 0) then begin
       {$IFDEF DEBUG}
           DoDebug('DebugWebPage - Erreur d''ouverture: ' + Fichier);
       {$ENDIF}

       exit;
    end;

    WriteLn(F, PageWeb);

    CloseFile(F);
end;

function TPlayerGestion.ProceedGetMessagesList(ListMsg: TCollectionOGMessage; bDelMessageSite: boolean; bDownloadRapportCombat: boolean): integer;
label lRedo;
var sURL, sPageWeb, sData: string;
    iRedo, i: integer;
    pe: POGMessage;
begin


    Result := CNT_ERROR_FATAL;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGetMessagesList - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGetMessagesList - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;



    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sURL := FParsingPages.pMenuLeft.GetLink(mliMessages);

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedGetMessagesList - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;


    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page MessagesListe: ' + sURL);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, '', FsockHTTP);


    // <a href="#" onclick="fenster('bericht.php?xtid&bericht=3881889', 'Bericht');" >

    
    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGetMessagesList - Erreur dl');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SHOULD_RELOGIN;

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_MESSAGELIST);
          {$ENDIF}
          exit;
       end;

       goto lRedo;

    end else if cParsing.ParsingMessages(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGetMessagesList - Le parsing a échoué (FParserMessagesList)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_MESSAGELIST);
       {$ENDIF}

       exit;

    end else begin

       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
           if FDebugWebPageActiveWhenSuccess then
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_MESSAGELIST);
       {$ENDIF}

    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(sURL);



    // Copie les messages dans la liste
    ListMsg.DuplicationZoneMemoireFromList(cParsing.pMessages.MessageList);



    if bDownloadRapportCombat and (cParsing.pMessages.MessageList.Count > 0) then begin
       // on doit télécharger les rapports de combat AVANT d'effacer les messages
       for i := 0 to cParsing.pMessages.MessageList.Count - 1 do begin
          pe := cParsing.pMessages.MessageList.Items[i];

          if pe.RapportCombatLink <> '' then begin
             // télécharge le rapport de combat
             {$IFDEF DEBUG}
                DoDebug('Téléchargement rapport de combat: ' + pe.RapportCombatLink);
             {$ENDIF}

             sPageWeb := myGETorPOST_InTamponX(pe.RapportCombatLink, '', FsockHTTP);

             if (sPageWeb <> modDL_ERREUR_DL_STR) and (sPageWeb <> mcDL_MUST_RELOGIN) and (length(sPageWeb) > 100) and (FsockHTTP.StatusCode = 200) then begin
                // le sauvegarde
                SauvegardeRapportCombat(pe, sPageWeb);

                DoSleep(2500);

             end else begin
                {$IFDEF DEBUG}
                   DoDebug('Echec de téléchargement du rapport de combat');
                {$ENDIF}
             end;

          end;
       end;
    end;


    if bDelMessageSite and (cParsing.pMessages.MessageList.Count > 0) then begin
       // supprime les messages récoltés du site web
       // La condition (FParserMessagesList.MessageList.Count > 0) permet de
       // s'assurer qu'il y a des messages à supprimer, car en cas de bug de
       // téléchargement de la page, il ne faudrai pas supprimer de messages

       sURL := cParsing.pMessages.PageToPost;

       sData := cParsing.pMessages.DataToPost;
       sData := sfcRemplace(sData, CNT_MESSAGE_IN_TYPEEFFACEMENT, CNT_MESSAGE_VAL_TYPEEFFACEMENT_MSGMONTRES);

       {$IFDEF DEBUG}
           DoDebug('Post les données d''effacement de message, url: ' + sURL);
           DoDebug('Données: ' + sData);
       {$ENDIF}

       if FsockHTTP.State <> httpReady then begin
           // composant pas prêt
           Sleep(5);
       end;

       sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);

       if (sPageWeb = modDL_ERREUR_DL_STR) or (length(sPageWeb) < 100) then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedGetMessagesList - L''effacement des messages montrés a échoué');
          {$ENDIF}

          Result := CNT_ERROR_SHOULD_RELOGIN;
          exit;
       end;

    end;

    Result := 1;


end;


function TPlayerGestion.ProceedReturnFlotte(FlotteID: PFlotteOwnUID): integer;
var r: integer;
    peFlotte: PFlotteListEnVoyage;
    sPageWeb, backupURL: string;
begin

    r := RetreiveFlotte1Page;

    if r < 0 then begin
       // echec de téléchargement de la page flotte1
       Result := r;
       exit;
    end;



    peFlotte := cParsing.pFlotte1.FlotteList.GetFromUID(FlotteID);

    if peFlotte = nil then begin
       // flotte inexistante
       {$IFDEF DEBUG}
          DoDebug('ProceedReturnFlotte - Flotte introuvable dans la liste');
       {$ENDIF}

       Result := -7;
       exit;

    end else if peFlotte.ReturnDataURL = '' then begin
       // la flotte est peut-être déjà dans le sens retour
       if peFlotte.Direction = odRetour then begin
          Result := 1;

       end else begin
          Result := -9;
       end;

       exit;

    end;

    // sinon rappelle la flotte
    

    // On télécharge la page web
    // on provient de la page du menu de flotte (flotte1)
    FsockHTTP.Reference := FParsingPages.pMenuLeft.GetLink(mliFlotte);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page de soumission du formulaire: ' + peFlotte.ReturnDataURL);
    {$ENDIF}

    if copy(peFlotte.ReturnDataURL, 1, 7) <> 'http://' then begin
       // erreur de lien

       {$IFDEF DEBUG}
          DoDebug('ProceedReturnFlotte - Erreur de lien pour l''action de "retour"');
       {$ENDIF}

       Result := -8;
       exit;
    end;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Données: ' + peFlotte.ReturnDataToPost);
    {$ENDIF}

    // une fois le parsing effectué, peFlotte n'existera plus en mémoire
    backupURL := peFlotte.ReturnDataURL;

    sPageWeb := myGETorPOST_InTamponX(peFlotte.ReturnDataURL, peFlotte.ReturnDataToPost, FsockHTTP);


    //
    // On post les données et la page que l'on obtient est la
    // page Flotte1
    // il n'y a pas de redirection comme pour les ressources
    // on utilise donc le parser de la page flotte1
    //

    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedReturnFlotte - Erreur dl - Page non téléchargé');
       {$ENDIF}

    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       // doit se relogger
       {$IFDEF DEBUG}
           DoDebug('ProceedReturnFlotte - Doit se relogger');
       {$ENDIF}

       Result := CNT_ERROR_MUST_RELOGIN;
       exit;

       

    end else if cParsing.ParsingFlotte1(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedReturnFlotte - Le parsing flotte 1 a échoué (FParserFlotte1Vaisseaux)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
       {$ENDIF}

       Result := CNT_ERROR_PARSING;
       exit;

    end;
    
    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(backupURL);

    // Met à jour la dernière page dl
    //FLastPageWebDL := FParserFlotte1Vaisseaux;


    Result := 1;

end;



function TPlayerGestion.RetreiveFlotte1Page(bSansParsing: boolean = false): integer;
label lRedo;
var sURL, sPageWeb, sData: string;
    iRedo: integer;
    bBackup: boolean;

    cPlanete: TPlaneteInfo;
begin



    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Un autre job est déjà en cours d''exécution');
       {$ENDIF}
       Result := CNT_LOGIN_ERROR_AUTRE_ACTION_ENCOURS;
       exit;
    end;


    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Composant HTTP non prêt');
       {$ENDIF}
       Result := CNT_LOGIN_ERROR_SOCKETNONPRET;
       exit;
    end;

    Result := CNT_ERROR_FATAL;

    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sURL := FParsingPages.pMenuLeft.GetLink(mliFlotte);

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;


    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page Flotte 1: ' + sURL);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, '', FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Erreur dl - Page non téléchargé');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SOCKET;

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
          {$ENDIF}

          exit;
       end;

       DoSleep(700);
       goto lRedo;

    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       // doit se relogger
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Doit se relogger');
       {$ENDIF}

       Result := CNT_ERROR_MUST_RELOGIN;
       exit;


    end;


    if bSansParsing = false then begin
    
       if cParsing.ParsingFlotte1(sPageWeb) = false then begin
          {$IFDEF DEBUG}
              DoDebug('RetreiveFlotte1Page - Le parsing flotte 1 a échoué (FParserFlotte1Vaisseaux)');
          {$ENDIF}

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
          {$ENDIF}

          Result := CNT_ERROR_PARSING;
          exit;


       end else begin
          // succès
          {$IFDEF DEBUGFILE_WHEN_SUCCESS}
              if FDebugWebPageActiveWhenSuccess then
                 DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
          {$ENDIF}

       end;


       if cParsing.pFlotte1.FlotteMax > 1 then begin
          FMaxFlotteSlot := cParsing.pFlotte1.FlotteMax;
       end else begin
          if FMaxFlotteSlot > 1 then begin
             DoDebug('ATTENTION: Repérage de bug possible... page web sauvegardée...');
             
             bBackup := FDebugWebPageActive;
             FDebugWebPageActive := true;
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
             FDebugWebPageActive := bBackup;
          end else begin
             FMaxFlotteSlot := cParsing.pFlotte1.FlotteMax;
          end;

       end;


       cParsing.SetURLOfThisPage(sURL);
       cParsing.pHeader.BackupCreate;

       // Met à jour la dernière page dl
       //FLastPageWebDL := FParserFlotte1Vaisseaux;

       CheckCurrentPlanetFromHeader();



       FCurrentPlanete.FLastRessources     := cParsing.pHeader.CurrRessource;
       FCurrentPlanete.FLastRessourcesDate := DateTimeToUnix(Now);

    end else begin
       {$IFDEF DEBUG}
           DoDebug('RetreiveFlotte1Page - Skip');
       {$ENDIF}

    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);


    // modifie le lien de référence
    FsockHTTP.Reference := sURL;

    Result := 1;
end;




function TPlayerGestion.ProceedEnvoiDeFlotte(Infos: PFlotteEnvoiData): TFlotteEnvoiRes;
label lEnd;
var NbVaisseauxSel: integer;
    sURL, sPageWeb, sData: string;
    //iRedo: integer;
    bOrdreNotFound: boolean;
    x: integer;
begin

    Result := ferFatalError;

    
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Cible: ' + mbtPlanetLocationToStr(Infos.Cible) + ' - ' + mbtCibleTypeToStr(Infos.CibleType));
           DoDebug('ProceedEnvoiDeFlotte - Ordre: ' + mamOrdreToStr(Infos.Ordre) + ' (Vitesse: ' + IntToStr(Infos.Vitesse) + ')');

           if (Infos.Ressources.Metal = 0) and (Infos.Ressources.Cristal = 0) and (Infos.Ressources.Deuterium = 0) then begin
              DoDebug('ProceedEnvoiDeFlotte - Ressource: Aucune');
           end else begin
              DoDebug('ProceedEnvoiDeFlotte - Ressources.Metal: ' + IntToStr(Infos.Ressources.Metal));
              DoDebug('ProceedEnvoiDeFlotte - Ressources.Cristal: ' + IntToStr(Infos.Ressources.Cristal));
              DoDebug('ProceedEnvoiDeFlotte - Ressources.Deuterium: ' + IntToStr(Infos.Ressources.Deuterium));
           end;
       {$ENDIF}
       

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Un autre job est déjà en cours d''exécution');
       {$ENDIF}
       exit;
    end;




    //
    // On part du principe que les vaisseaux sont déjà sélectionnés
    //

    

    // On vérifie si il y a des vaisseaux à envoyer
    if cParsing.pFlotte1.VaisseauxList.ExistVaisseauxDeplacable = false then begin
       // aucun vaisseaux déplaçable

       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Aucun vaiseaux déplaçable');
       {$ENDIF}

       Result := ferNoVaisseaux;
       FJobOccupation := jobpAucun;
       exit;
    end;


    // vérifie qu'il y a bien des vaisseaux de sélectionnés
    if cParsing.pFlotte1.VaisseauxList.GetNbVaisseauxSelectionnes = 0 then begin
       // aucun vaisseaux de sélectionnés

       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Aucun vaiseaux sélectionnés');
       {$ENDIF}

       Result := ferNoVaisseaux;
       FJobOccupation := jobpAucun;
       exit;
    end;



    if (Infos.Vitesse < 1) or (Infos.Vitesse > 10) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - iSpeedRatio Invalide');
       {$ENDIF}

       Result := ferFatalError;
       FJobOccupation := jobpAucun;
       exit;
    end;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Composant HTTP non prêt');
       {$ENDIF}

       Result := ferShouldRetryButNotError;
       FJobOccupation := jobpAucun;
       exit;
    end;


    // le vérrou est mis seulement ici
    FJobOccupation := jobpOccupe;


    // Les vaisseaux sont supposés déjà sélectionnés, maintenant post les données
    sURL  := cParsing.pFlotte1.URLToPost;
    sData := cParsing.pFlotte1.VaisseauxList.GetDataToPost;


    if sURL = '' then begin
       // On a atteint le nombre de flotte maximale
       Result := ferFlotteMaxAtteinte;
       FJobOccupation := jobpAucun;
       exit;
    end;

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de vaisseaux, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Erreur dl page 2 postage choix vaisseaux');
       {$ENDIF}

       Result := ferSocketError;
       FJobOccupation := jobpAucun;
       exit;

    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - page 2 postage choix vaisseaux -> Doit se relogger');
       {$ENDIF}

       Result := ferNotOrReLoginCertain;
       FJobOccupation := jobpAucun;
       exit;

    end else if cParsing.ParsingFlotte2(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Le parsing 2 a échoué (FParserFlotte2Destination)');
       {$ENDIF}



       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;

       end else begin
          {$IFDEF DEBUG}
              DoDebug('ProceedEnvoiDeFlotte - Le parsing 2 a échoué -> Erreur fatale');
              DoDebug('ProceedEnvoiDeFlotte - Taille de la page: ' + IntToStr(Length(sPageWeb)));
              DoDebug(sPageWeb);
              DoDebug('ProceedEnvoiDeFlotte - Fin de la page');
          {$ENDIF}
          // En attendant de debogger, on met should retry
          // Result := ferFatalError;
          Result := ferShouldRetry;

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE2);
          {$ENDIF}
       end;

       goto lEnd;
    end;





    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);

    if cParsing.pFlotte2.PageToPost = '' then begin
       // erreur
       // ceci se produit lorsque l'on réessaye un envoi
       // lors du second essai, la fonction est à nouveau appelé sans avoir
       // a nouveau téléchargé la page 1

       {$IFDEF DEBUG}
          DoDebug('ProceedEnvoiDeFlotte - Le lien de la page flotte2 est invalide');
       {$ENDIF}
       Result := ferShouldRetryButNotError;

       goto lEnd;
    end;
    cParsing.SetURLOfThisPage(sURL);



    sData := cParsing.pFlotte2.DataToPost;


    if mbtIsLune(Infos.Cible) then begin
       x := mbtGetRealPosition(Infos.Cible.Position);

       {$IFDEF DEBUG}
          DoDebug('ProceedEnvoiDeFlotte - Coordonnées sous forme de lune (ce qui ne devrait pas être le cas)');
       {$ENDIF}


       // s'assure alors que le type est bien Lune
       Infos.CibleType := ctLune;
    end else begin
       x := Infos.Cible.Position;
    end;


    // Choisi les options
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_GALAXYCIBLE   , IntToStr(Infos.Cible.Galaxie));
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SYSTEMCIBLE   , IntToStr(Infos.Cible.SystemSolaire));
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_PLANETPOSCIBLE, IntToStr(x));

    case Infos.CibleType of
       ctNeant:   begin
          // erreur
          Result := ferFatalError;
          goto lEnd;
       end;
       ctPlanete: sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_PLANETE);
       ctRuines:  sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_RUINES);
       ctLune:    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_LUNE);
    end;

    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SPEEDRATIO, IntToStr(Infos.Vitesse));


    sURL := cParsing.pFlotte2.PageToPost;

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de destination, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;



    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);



    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Erreur dl page 3 postage choix destination');
       {$ENDIF}

       Result := ferSocketError;
       goto lEnd;


    end else if cParsing.ParsingFlotte3(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Le parsing 3 a échoué (FParserFlotte3OrdreRessources)');
       {$ENDIF}


       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;

       end else begin

          {$IFDEF DEBUG}
              DoDebug('ProceedEnvoiDeFlotte - Le parsing 3 a échoué -> Erreur fatale');
              DoDebug('ProceedEnvoiDeFlotte - Taille de la page: ' + IntToStr(Length(sPageWeb)));
              DoDebug(sPageWeb);
              DoDebug('ProceedEnvoiDeFlotte - Fin de la page');
          {$ENDIF}

          // En attendant de debogger, on met should retry
          // Result := ferFatalError;
          Result := ferShouldRetry;

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE3);
          {$ENDIF}

       end;


       goto lEnd;
    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(sURL);



    sURL := cParsing.pFlotte3.PageToPost;



    sData := cParsing.pFlotte3.DataToPost;





    if cParsing.pFlotte3.ExistOrdre = false then begin
       // pas d'ordre...
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Aucun ordre de disponible');
       {$ENDIF}

       
       Result := ferFatalError;
       goto lEnd;
    end;
    
    bOrdreNotFound := false;

    case Infos.Ordre of
       ooNeant: bOrdreNotFound := true;
       ooAttaquer: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_ATTAQUER) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ATTAQUER);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooTransport: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_TRANSPORT) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_TRANSPORT);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooExploiter: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_EXPLOITER_RUINES) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_EXPLOITER_RUINES);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooEspionner: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_ESPIONNAGE) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ESPIONNAGE);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooBaser: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_BASER) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_BASER);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooColoniser: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_COLONISER) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_COLONISER);
                   end else begin
                      bOrdreNotFound := true;
                   end;
    end;

    if bOrdreNotFound then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Aucun ordre de valide...');
       {$ENDIF}
       goto lEnd;
    end;


    if Infos.Ressources.Metal < 0 then begin
       Infos.Ressources.Metal := 0;
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Attention: Métal négatif');
       {$ENDIF}
    end;
    if Infos.Ressources.Cristal < 0 then begin
       Infos.Ressources.Cristal := 0;
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Attention: Cristal négatif');
       {$ENDIF}
    end;
    if Infos.Ressources.Deuterium < 0 then begin
       Infos.Ressources.Deuterium := 0;
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Attention: Deutérium négatif');
       {$ENDIF}
    end;


    // définit les ressources
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_METAL    , IntToStr(Infos.Ressources.Metal));
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_CRISTAL  , IntToStr(Infos.Ressources.Cristal));
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_DEUTERIUM, IntToStr(Infos.Ressources.Deuterium));


    {$IFDEF DEBUG}
        DoDebug('Post les données de choix des ressources, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;




    // Post les données et télécharge donc la page de confirmation d'envoi
    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Erreur dl page finale');
       {$ENDIF}

       Result := ferShouldRetry;
       goto lEnd;

    end else if length(sPageWeb) < 90 then begin
       // Il arrive parfois que la flotte ne s'envoye pas (avec un simple mot allemand)
       // Note: la page affichant qu'il manque du carburant a pour taille: 0,23 KB (236 bytes)
       Result := ferShouldRetry;

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          {$IFDEF DEBUG}
              DoDebug('ProceedEnvoiDeFlotte - Doit se relogger...');
          {$ENDIF}
          Result := ferNotOrReLoginCertain;
       end;


       goto lEnd;


    end else if cParsing.ParsingFlotte4(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedEnvoiDeFlotte - Le parsing 4 a échoué (FParserFlotte4Confirmation)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE4);
       {$ENDIF}



       if cParsing.IsValidPage then begin
          // la page web a cependant bien été téléchargé
          {$IFDEF DEBUG}
              DoDebug('ProceedEnvoiDeFlotte - Le parsing 4 a échoué (La page web a bien été téléchargé)');
          {$ENDIF}
       end;

       Result := ferShouldRetry;

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger  (rare)
          Result := ferNotOrReLoginCertain;
       end;

       goto lEnd;

    end;

    cParsing.SetURLOfThisPage(sURL);

    Result := GetResultFromFlotteConfirmation(Infos.Cible);


lEnd:
    cParsing.SetLastPageFlotte1;
    FJobOccupation := jobpAucun;
    cParsing.pHeader.BackupRestaure;

end;



function TPlayerGestion.ProceedFastEvacuation(Cible: TPlanetLocation; iSpeedRatio: integer; bWhere: TOGDestinationType; bMinVaisseaux: integer; xOrdre: TOGOrdre): TFlotteEnvoiRes;
var NbVaisseauxSel: integer;
    sURL, sPageWeb, sData: string;
    //iRedo: integer;
    bOrdreNotFound: boolean;
begin

    Result := ferFatalError;


    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Un autre job est déjà en cours d''exécution');
       {$ENDIF}
       exit;
    end;



   if RetreiveFlotte1Page < 0 then begin
      // erreur de récupération de la page de flotte
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Impossible de télécharger la page des vaisseaux');
       {$ENDIF}


       exit;
   end;

    FJobOccupation := jobpOccupe;

    // On vérifie si il y a des vaisseaux à envoyer
    if cParsing.pFlotte1.VaisseauxList.ExistVaisseauxDeplacable = false then begin
       // aucun vaisseaux déplaçable
       Result := ferNoVaisseaux;

       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Aucun vaiseaux déplaçable');
       {$ENDIF}

       FJobOccupation := jobpAucun;
       exit;
    end;



    if (iSpeedRatio < 1) or (iSpeedRatio > 10) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - iSpeedRatio Invalide');
       {$ENDIF}

       iSpeedRatio := 1;
    end;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - Composant HTTP non prêt');
       {$ENDIF}

       FJobOccupation := jobpAucun;
       exit;
    end;


    // Selectionne tous les vaisseaux
    NbVaisseauxSel := cParsing.pFlotte1.VaisseauxList.SelectionneTousLesVaisseaux;
    if NbVaisseauxSel < bMinVaisseaux then begin
       // pas assez de vaisseaux
       {$IFDEF DEBUG}
           DoDebug(format('ProceedFastEvacuation - Pas assez de vaisseaux à quai à envoyer (%d sur %d)', [NbVaisseauxSel, bMinVaisseaux]));
       {$ENDIF}

       Result := ferNoVaisseaux;
       
       FJobOccupation := jobpAucun;
       exit;
    end;



    // Les vaisseaux ont été sélectionné, maintenant post les données
    sURL  := cParsing.pFlotte1.URLToPost;
    sData := cParsing.pFlotte1.VaisseauxList.GetDataToPost;


    if sURL = '' then begin
       // On a atteint le nombre de flotte maximale
       Result := ferFlotteMaxAtteinte;
       FJobOccupation := jobpAucun;
       exit;
    end;

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de vaisseaux, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Erreur dl page 2 postage choix vaisseaux');
       {$ENDIF}

       
       Result := ferSocketError;
       FJobOccupation := jobpAucun;
       exit;

    end else if cParsing.ParsingFlotte2(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Le parsing 2 a échoué (FParserFlotte2Destination)');
       {$ENDIF}

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;
       end;

       FJobOccupation := jobpAucun;
       exit;
    end;




    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(sURL);



    sData := cParsing.pFlotte2.DataToPost;

    // Choisi les options
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_GALAXYCIBLE, IntToStr(Cible.Galaxie));
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SYSTEMCIBLE, IntToStr(Cible.SystemSolaire));
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_PLANETPOSCIBLE, IntToStr(Cible.Position));

    case bWhere of
       ctNeant:   sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_PLANETE);
       ctPlanete: sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_PLANETE);
       ctRuines:  sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_RUINES);
       ctLune:    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_LUNE);
    end;

    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SPEEDRATIO, IntToStr(iSpeedRatio));


    sURL := cParsing.pFlotte2.PageToPost;

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de destination, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;



    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);



    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Erreur dl page 3 postage choix destination');
       {$ENDIF}

       Result := ferSocketError;
       FJobOccupation := jobpAucun;
       exit;



    end else if cParsing.ParsingFlotte3(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Le parsing 3 a échoué (FParserFlotte3OrdreRessources)');
       {$ENDIF}

       // Should retry dans ce cas
       Result := ferShouldRetry;

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;
       end;


       FJobOccupation := jobpAucun;
       exit;
    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(sURL);




    sURL := cParsing.pFlotte3.PageToPost;



    sData := cParsing.pFlotte3.DataToPost;





    if cParsing.pFlotte3.ExistOrdre = false then begin
       // pas d'ordre...
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Aucun ordre de disponible');
       {$ENDIF}

       FJobOccupation := jobpAucun;
       exit;
    end;
    
    bOrdreNotFound := false;

    case xOrdre of
       ooNeant: bOrdreNotFound := true;
       ooAttaquer: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_ATTAQUER) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ATTAQUER);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooTransport: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_TRANSPORT) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_TRANSPORT);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooExploiter: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_EXPLOITER_RUINES) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_EXPLOITER_RUINES);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooEspionner: bOrdreNotFound := true;
       ooBaser: if cParsing.pFlotte3.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_BASER) then begin
                      sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_BASER);
                   end else begin
                      bOrdreNotFound := true;
                   end;
       ooColoniser: bOrdreNotFound := true;
    end;

    if bOrdreNotFound then begin
       // choisi un ordre au hasard
       sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_TRANSPORT);
       sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_EXPLOITER_RUINES);
       sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ATTAQUER);
       sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ESPIONNAGE);
       sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_COLONISER);

       if pos(CNT_FLOTTE3_IN_ORDRE, sData) > 0 then begin
          // toujours aucun ordre valide
          {$IFDEF DEBUG}
             DoDebug('ProceedFastEvacuation - Aucun ordre de valide...');
          {$ENDIF}
          FJobOccupation := jobpAucun;
          exit;
       end;
    end;



    // définit les ressources
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_METAL    , IntToStr(cParsing.pHeader.CurrRessource.Metal));
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_CRISTAL  , IntToStr(cParsing.pHeader.CurrRessource.Cristal));
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_DEUTERIUM, IntToStr(cParsing.pHeader.CurrRessource.Deuterium));

    
    {$IFDEF DEBUG}
        DoDebug('Post les données de choix des ressources, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;




    // Post les données et télécharge donc la page de confirmation d'envoi
    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - Erreur dl page finale');
       {$ENDIF}

       Result := ferShouldRetry;
       FJobOccupation := jobpAucun;
       exit;

    end else if length(sPageWeb) < 700 then begin
       // Il arrive parfois que la flotte ne s'envoye pas (avec un simple mot allemand)
       Result := ferShouldRetry;

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;
       end;

       
       FJobOccupation := jobpAucun;
       exit;

    end else if cParsing.ParsingFlotte4(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedFastEvacuation - Le parsing 4 a échoué (FParserFlotte4Confirmation)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE4);
       {$ENDIF}

       if cParsing.IsValidPage then begin
          // la page web a cependant bien été téléchargé
          {$IFDEF DEBUG}
              DoDebug('ProceedFastEvacuation - Le parsing 4 a échoué (La page web a bien été téléchargé)');
          {$ENDIF}
       end;

       Result := ferShouldRetry;

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;
       end;

       FJobOccupation := jobpAucun;
       exit;

    end;

    Result := GetResultFromFlotteConfirmation(Cible);


    
    FJobOccupation := jobpAucun;
end;



function TPlayerGestion.ProceedAttaque(Cible: TPlanetLocation; iSpeedRatio: integer = 10; bAttaqueLune: boolean = false): TFlotteEnvoiRes;
var InfosAttaque: TFlotteEnvoiData;
begin

    Result := ferFatalError;


    // On vérifie si il y a des vaisseaux à envoyer
    if cParsing.pFlotte1.VaisseauxList.DoExistVaisseauxAEnvoyer = false then begin
       // c'est une erreur fatale car les vaisseaux sont choisit par l'utilisateur
       Result := ferFatalError;

       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - Aucun vaiseaux choisi');
       {$ENDIF}

       exit;
    end;

    if (iSpeedRatio < 1) or (iSpeedRatio > 10) then begin
       Result := ferFatalError;

       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - iSpeedRatio Invalide');
       {$ENDIF}

       exit;
    end;


    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedAttaque - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;



    InfosAttaque.Cible     := Cible;
    InfosAttaque.CibleType := ctPlanete;
    InfosAttaque.Vitesse   := iSpeedRatio;
    InfosAttaque.Ordre     := ooAttaquer;
    InfosAttaque.Ressources.Metal     := 0;
    InfosAttaque.Ressources.Cristal   := 0;
    InfosAttaque.Ressources.Deuterium := 0;

    if mbtIsLune(Cible) or bAttaqueLune then begin
       InfosAttaque.Cible.Position := mbtGetRealPosition(Cible.Position);
       InfosAttaque.CibleType := ctLune;
    end;


    Result := ProceedEnvoiDeFlotte(@InfosAttaque);
    FJobOccupation := jobpAucun;

    
end;

function TPlayerGestion.GetResultFromFlotteConfirmation(Cible: TPlanetLocation): TFlotteEnvoiRes;
begin


    // compare les coordonnées
    if CompareLocation(Cible, cParsing.pFlotte4.FlotteArrivee) then begin
       Result := ferSuccess;

    end else begin
       // Il se peut que la planète soit invalide (décoloniser, champs d'astéoride, ou protection
       // des noob, ou autre)
       // Ou encore que l'on ai plus de deutérieur et dans ce cas c'est plus grave car tout les sondages
       // échoueront...

       if mbtIsLune(Cible) then begin
          Cible.Position := mbtGetRealPosition(Cible.Position);

          if CompareLocation(Cible, cParsing.pFlotte4.FlotteArrivee) then begin
             // meme location
             // c'est bon
             Result := ferSuccess;
             exit;
          end;

       end;


       if cParsing.pFlotte4.IsPlaneteVide then begin
          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - La planete n''existe plus');
          {$ENDIF}

          Result := ferPlaneteInvalid;

       end else if cParsing.pFlotte4.IsPlaneteProtectNoob then begin
          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - La planete a la protection des newbz');
          {$ENDIF}

          Result := ferPlaneteInvalid;

       end else if cParsing.pFlotte4.IsPlaneteModeVacance then begin
          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - La planete est en mode vacance');
          {$ENDIF}

          Result := ferPlaneteInvalid;


       end else if cParsing.pFlotte4.IsPlaneteCantBeAccessible then begin
          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - Planète invalide (IsPlaneteCantBeAccessible = true)');
          {$ENDIF}

          Result := ferPlaneteInvalid;

       end else if cParsing.pFlotte4.IsDeuteriumError then begin

          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - Pas assez de deutérium');
          {$ENDIF}

          Result := ferPlaneteInvalid;


       end else  begin

          {$IFDEF DEBUG}
              DoDebug('GetResultFromFlotteConfirmation - La page de confirmation contient une coordonnées différente pour la cible');
          {$ENDIF}

          Result := ferFatalError;
       end;

    end;


end;


function TPlayerGestion.ProceedSondage(Cible: TPlanetLocation; NbSondes: integer; iSpeedRatio: integer = 10): TFlotteEnvoiRes;
label lRedo;
var sURL, sPageWeb, sData: string;
    iRedo: integer;

    InfosSondage: TFlotteEnvoiData;
begin

    // ferFatalError, ferNotLogin, ferSuccess, ferNoVaisseaux, ferFlotteMaxAtteinte
    Result := ferFatalError;

    if NbSondes = 0 then begin
       // Erreur fatale
       exit;
    end;



    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;



    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sURL := FParsingPages.pMenuLeft.GetLink(mliFlotte);

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := ferFatalError;
       exit;
    end;


    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page flotte1: ' + sURL);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, '', FsockHTTP);


    if (sPageWeb = modDL_ERREUR_DL_STR) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Erreur download (flotte1)');
       {$ENDIF}

       if iRedo > 2 then begin
          //Result := ferNotOrReLogin;
          Result := ferSocketError;


          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
          {$ENDIF}

          exit;
       end;

       goto lRedo;

    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Doit se relogger');
       {$ENDIF}

       Result := ferNotOrReLoginCertain;
       exit;

    end else if (length(sPageWeb) < 800)  then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Page web trop petite (flotte1)');
       {$ENDIF}

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // doit se relogger
          Result := ferNotOrReLoginCertain;

          // pas la peine de réessayer
          exit;
       end;

       if iRedo > 2 then begin
          // Erreur de parsing, fatale

          Result := ferFatalError;
          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
          {$ENDIF}

          exit;
       end;

       goto lRedo;


    end else if cParsing.ParsingFlotte1(sPageWeb) = false then begin
       Result := ferFatalError;
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Le parsing 1 a échoué (FParserFlotte1Vaisseaux)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
       {$ENDIF}

       exit;

    end else begin
    
       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
           if FDebugWebPageActiveWhenSuccess then
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE1);
       {$ENDIF}
    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    cParsing.SetURLOfThisPage(sURL);

    // mets à jour les ressources
    FCurrentPlanete.FLastRessources     := cParsing.pHeader.CurrRessource;
    FCurrentPlanete.FLastRessourcesDate := DateTimeToUnix(Now);


    // Maintenant on choisit les vaisseaux que l'on veut envoyer
    if cParsing.pFlotte1.VaisseauxList.ExistVaisseauxDeplacable = false then begin
       // aucun vaisseau ou que des sat solaire...
       Result := ferNoVaisseaux;

       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Pas de vaisseaux déplaçable sur cette planete');
       {$ENDIF}

       exit;
    end;

    // Spécifie le nombre de vaisseaux
    // C'est 210 le GID des sondes

    if cParsing.pFlotte1.VaisseauxList.SetVaisseauxAUtiliser(CNT_GID_VAISSEAUX_SONDES, NbSondes) = false then begin
       // Pas de sonde sur cette planète
       Result := ferNoVaisseaux;

       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Pas de sondes désirées sur cette planète, sondes voulues: ' + IntToStr(NbSondes));
       {$ENDIF}

       sURL := cParsing.pFlotte1.URLToPost;
       if sURL = '' then begin
          // On a atteint le nombre de flotte maximale
          Result := ferFlotteMaxAtteinte;
          {$IFDEF DEBUG}
              DoDebug('ProceedSondage - (max flotte atteint également)');
          {$ENDIF}
       end;

       exit;
    end;


    InfosSondage.Cible     := Cible;
    InfosSondage.CibleType := ctPlanete;
    InfosSondage.Vitesse   := iSpeedRatio;
    InfosSondage.Ordre     := ooEspionner;
    InfosSondage.Ressources.Metal     := 0;
    InfosSondage.Ressources.Cristal   := 0;
    InfosSondage.Ressources.Deuterium := 0;

    if mbtIsLune(Cible) then begin
       InfosSondage.Cible.Position := mbtGetRealPosition(Cible.Position);
       InfosSondage.CibleType := ctLune;
    end;

    Result := ProceedEnvoiDeFlotte(@InfosSondage);

    
    FJobOccupation := jobpAucun;

(*
    // Les vaisseaux ont été sélectionné, maintenant post les données
    sURL := FParserFlotte1Vaisseaux.URLToPost;
    sData := FParserFlotte1Vaisseaux.VaisseauxList.GetDataToPost;


    if sURL = '' then begin
       // On a atteint le nombre de flotte maximale
       Result := ferFlotteMaxAtteinte;
       exit;
    end;



    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de vaisseaux, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if (sPageWeb = modDL_ERREUR_DL_STR) or (length(sPageWeb) < 512) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Erreur dl page 2 postage choix vaisseaux');
       {$ENDIF}

       Result := ferNotOrReLogin;
       exit;

    end else if FParserFlotte2Destination.ParseBuffer(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Le parsing 2 a échoué (FParserFlotte2Destination)');
       {$ENDIF}


       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE2);
       {$ENDIF}

       exit;

    end else begin

       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
           if FDebugWebPageActiveWhenSuccess then
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE2);
       {$ENDIF}
    end;


    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    FParserFlotte2Destination.SetURLOfThisPage(sURL);



    sData := FParserFlotte2Destination.DataToPost;

    // Choisit les options
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_GALAXYCIBLE, IntToStr(Cible.Galaxie));
    sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SYSTEMCIBLE, IntToStr(Cible.SystemSolaire));

    if mbtIsLune(Cible.Position) then begin
       sData := sfcRemplace(sData, CNT_FLOTTE2_IN_PLANETPOSCIBLE, IntToStr(mbtGetRealPosition(Cible.Position)));
       sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_LUNE);
    end else begin
       sData := sfcRemplace(sData, CNT_FLOTTE2_IN_PLANETPOSCIBLE, IntToStr(Cible.Position));
       sData := sfcRemplace(sData, CNT_FLOTTE2_IN_CIBLETYPE, CNT_FLOTTE2_VAL_CIBLETYPE_PLANETE);
    end;

    //sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SPEEDRATIO, '10');
   sData := sfcRemplace(sData, CNT_FLOTTE2_IN_SPEEDRATIO, IntToStr(iSpeedRatio));


    sURL := FParserFlotte2Destination.PageToPost;

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix de destination, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);



    if (sPageWeb = modDL_ERREUR_DL_STR) or (length(sPageWeb) < 512) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Erreur dl page 3 postage choix destination');
       {$ENDIF}

       Result := ferNotOrReLogin;
       exit;



    end else if FParserFlotte3OrdreRessources.ParseBuffer(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Le parsing 3 a échoué (FParserFlotte3OrdreRessources)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE3);
       {$ENDIF}

       // Should retry dans ce cas
       Result := ferShouldRetry;
       exit;

    end else begin


       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
           if FDebugWebPageActiveWhenSuccess then
              DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE3);
       {$ENDIF}


    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);
    FParserFlotte3OrdreRessources.SetURLOfThisPage(sURL);



    sURL := FParserFlotte3OrdreRessources.PageToPost;


    if FParserFlotte3OrdreRessources.ExistThisOrdre(CNT_FLOTTE3_VAL_ORDRE_ESPIONNAGE) = false then begin
       // l'ordre espionnage n'existe pas...
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - L''ordre espionnage n''existe pas');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE3);
       {$ENDIF}

       exit;
    end;

    sData := FParserFlotte3OrdreRessources.DataToPost;

    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_METAL    , '0');
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_CRISTAL  , '0');
    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_DEUTERIUM, '0');

    sData := sfcRemplace(sData, CNT_FLOTTE3_IN_ORDRE, CNT_FLOTTE3_VAL_ORDRE_ESPIONNAGE);

    {$IFDEF DEBUG}
        DoDebug('Post les données de choix des ressources, url: ' + sURL);
        DoDebug('Données: ' + sData);
    {$ENDIF}

    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       Sleep(5);
    end;

    // Post les données et télécharge donc la page de confirmation d'envoi
    sPageWeb := myGETorPOST_InTamponX(sURL, sData, FsockHTTP);


    if (sPageWeb = modDL_ERREUR_DL_STR) or (length(sPageWeb) < 512) then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Erreur dl page finale');
       {$ENDIF}

       Result := ferShouldRetry;
       exit;

    end else if length(sPageWeb) < 60 then begin
       // Il arrive parfois que la flotte ne s'envoye pas (avec un simple mot allemand)
       Result := ferShouldRetry;
       exit;

    end else if FParserFlotte4Confirmation.ParseBuffer(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedSondage - Le parsing 4 a échoué (FParserFlotte4Confirmation)');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
           DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE4);
       {$ENDIF}

       Result := ferShouldRetry;
       exit;

    end;

    Result := GetResultFromFlotteConfirmation(Cible);

    {$IFDEF DEBUGFILE_WHEN_ECHEC}
       if Result = ferFatalError then begin
          DebugWebPage(sPageWeb, CNT_DEBUGFILE_FLOTTE4);
       end;
    {$ENDIF}
*)

end;





function TPlayerGestion.CheckCurrentPlanetFromHeader: boolean;
var cPlanete: TPlaneteInfo;
begin

    Result   := false;
    cPlanete := FPlaneteList.GetPlanete(FParsingPages.pHeader.Planete);



     if cPlanete = nil then begin
           //cPlanete := TPlaneteInfo.Create;
           //FPlaneteList.Add(cPlanete);

           {$IFDEF DEBUG}
              DoDebug('CheckCurrentPlanetFromHeader -> Planète différente de celle sur laquelle le robot croyait être - Et elle est INCONNUE du robot');
              DoDebug('CheckCurrentPlanetFromHeader -> La planète a peut-être été changé par le tunnel ?');
           {$ENDIF}

           Result := false;


     end else begin


        if FCurrentPlanete = nil then begin
           {$IFDEF DEBUG}
              if FInLogin then begin
                 DoDebug('CheckCurrentPlanetFromHeader -> Planete invalide (login en cours)');
              end else begin
                 DoDebug('CheckCurrentPlanetFromHeader -> Planete invalide (erreur fatale)');
              end;

           {$ENDIF}

        end else if cPlanete = FCurrentPlanete then begin
           // même pointeur

        end else begin
           // pointeur différent
           {$IFDEF DEBUG}
              DoDebug('CheckCurrentPlanetFromHeader -> Planète différente de celle sur laquelle le robot croyait être');
              DoDebug('CheckCurrentPlanetFromHeader -> La planète a peut-être été changé par le tunnel ?');
           {$ENDIF}

           FCurrentPlanete := cPlanete;
           Result := true;
        end;
     end;

end;


function TPlayerGestion.ProceedUpdateApercu(bOverrideURLAndReference: boolean = false): integer;
label lRedo, lMakeErr;
var sURL, sPageWeb: string;
    iRedo: integer;
    cPlanete: TPlaneteInfo;
begin


    Result := CNT_ERROR_USER;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;

    if FCurrentPlanete = nil then begin


       if bOverrideURLAndReference then begin
          {$IFDEF DEBUG}
             DoDebug('ProceedUpdateApercu - Aucune planète sélectionnée - Override (login en cours)');
          {$ENDIF}
       end else begin
          {$IFDEF DEBUG}
             DoDebug('ProceedUpdateApercu - Aucune planète sélectionnée - LogIn non effectué peut-être');
          {$ENDIF}
          exit;
       end;


    end;


    // On télécharge la page web

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;


    if bOverrideURLAndReference = false then begin
       // celle-ci provient suite à un clique dans le menu à gauche
       // Update: 0.77, le menu à gauche n'existe plus, et donc la page
       // de reference correspond toujours à la dernière page d/l
       //FsockHTTP.Reference := FParserMenu.URLOfThisFrame;

       if FParsingPages.LastPage <> nil then begin
          FsockHTTP.Reference := FParsingPages.LastPage.URLOfThisPage;
          
       end else begin
          FsockHTTP.Reference := '';
          {$IFDEF DEBUG}
             DoDebug('ProceedUpdateApercu - Erreur: e9874');
          {$ENDIF}
       end;



       // Obtient l'url à partir de l'id
       sURL := FParsingPages.pMenuLeft.GetLink(mliApercu);


    end else begin
       sURL := FParsingPages.pApercu.URLOfThisPage;
    end;

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;

    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page aperçu: ' + sURL);
    {$ENDIF}


    if FsockHTTP.State <> httpReady then begin
       // composant pas prêt
       DoSleep(50);
    end;


    sPageWeb := myGETorPOST_InTamponX(sURL, '', FsockHTTP);


    

    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Erreur dl');
       {$ENDIF}

 lMakeErr:
       if iRedo > 3 then begin
          Result := CNT_ERROR_SOCKET;
          FJobOccupation := jobpAucun;

          exit;
       end;

       goto lRedo;


    end else if sPageWeb = mcDL_MUST_RELOGIN  then begin

       Result := CNT_ERROR_MUST_RELOGIN;
       FJobOccupation := jobpAucun;
       
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Session expiré, doit se relogger');
       {$ENDIF}

       exit;



       // avant la page trop petite prennait en compte la valeur modDL_ERREUR_DL_STR
       // qui pouvait prendre la page web
       // a présent ce cas est exclu, si la page est trop petite c'est qu'il y
       // a un problème
       // on ne réessaye pas, on quitte avec une erreur fatale
       // edit: sauf si on se connecte avec un proxy bidon



       //goto lMakeErr;



    end else if FParsingPages.ParsingApercu(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Le parsing a échoué');
       {$ENDIF}


       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // la session à expirer
          Result := CNT_ERROR_MUST_RELOGIN;
          FJobOccupation := jobpAucun;

          {$IFDEF DEBUG}
              DoDebug('ProceedUpdateApercu - Session expiré, doit se relogger');
          {$ENDIF}
          exit;
       end;


       // il se peut aussi que le serveur lag
       if (FParsingPages.IsValidPage = false) or (length(sPageWeb) < 10)  then begin
          // page invalide
          // erreur du serveur
          // on l'identifie comme une erreur de socket
          Result := CNT_ERROR_SOCKET;

          {$IFDEF DEBUG}
            DoDebug('ProceedUpdateApercu -> Traité comme une erreur de socket (le serveur lag?)');
          {$ENDIF}


       end else begin
          // erreur de parsing malgrès une bonne taille de la page
          Result := CNT_ERROR_PARSING;

          // on affiche la page web car c'est assez grave
          {$IFDEF DEBUG}
            DoDebug('ProceedUpdateApercu - Page web:');
            DoDebug(sPageWeb);
            DoDebug('ProceedUpdateApercu - Fin Page web');
          {$ENDIF}

       end;



       // c'est une erreur de parsing, donc on quitte
       // on ne retélécharge pas la page web
       FJobOccupation := jobpAucun;
       exit;
       //goto lMakeErr;
    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);

 (*
    if FParserApercu.IsValidHeader = false then begin
       // impossible
       {$IFDEF DEBUG}
         DoDebug('ProceedUpdateApercu -> Erreur d''header...');
       {$ENDIF}
       Result := CNT_ERROR_PARSING;
       FJobOccupation := jobpAucun;
       exit;
    end;
*)


    // ATTENTION: C'est après le parsing que l'on définit l'url de la page
    // sinon les liens vers les autres planète ne seront pas complet
    FParsingPages.SetURLOfThisPage(sURL);


    // ATTENTION: Avec le tunnel, la planète sur laquelle on se situe n'est
    // pas forcément celle sur laquelle le robot croit être...
    // C'est d'autant plus important avec l'alerte d'attaque, car il se
    // peut que le robot vérifie si il y a une attaque pendant que le joueur joue sur le tunnel

    CheckCurrentPlanetFromHeader;




    if bOverrideURLAndReference then begin
       // les nouvelles planètes sont gérées et ajouté par ChangePlanete
       // SAUF pour le login
       // le login appelle à présent directement ProceedUpdateApercu
       // on doit donc vérifier ici si la planète existe bien
       FCurrentPlanete := FPlaneteList.GetPlanete(FParsingPages.pHeader.Planete);
       if FCurrentPlanete = nil then begin
          FCurrentPlanete := TPlaneteInfo.Create;
          FPlaneteList.Add(curPlanete);
       end;
    end;

    if FCurrentPlanete = nil then begin
       // echec...
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateApercu - Planète actuelle inconnue, erreur');
       {$ENDIF}
       Result := -978;
       exit;
    end;


    FCurrentPlanete.FNom                := FParsingPages.pApercu.NomPlanete;
    FCurrentPlanete.FNbCasesOccupees    := FParsingPages.pApercu.CasesOccupees;
    FCurrentPlanete.FNbCasesTotales     := FParsingPages.pApercu.CasesTotales;
    FCurrentPlanete.FLocation           := FParsingPages.pHeader.Planete;
    FCurrentPlanete.FLastRessources     := FParsingPages.pHeader.CurrRessource;
    FCurrentPlanete.FLastRessourcesDate := DateTimeToUnix(Now);


    //   FCurrentPlanete.SendDebugAllPlanetInfo;
    


    // Met à jour la dernière page dl
    // Update 0.77: Géré en interne dans FParsingPages
    //FLastPageWebDL := FParserApercu;

    FCurrentPlanete.pShouldUpdateAppercu := false;


    Result := 1;
    FJobOccupation := jobpAucun;
end;


function TPlayerGestion.ProceedModifRessourcesActivity: integer;
begin

    // on commence par télécharger la page web
    Result := ProceedUpdateRessource(false, false);
    if Result < 0 then begin
        {$IFDEF DEBUG}
            DoDebug('Echec de téléchargement de la page ressource');
        {$ENDIF}

        exit;
    end;




end;


function TPlayerGestion.ProceedRessourceCalcul: integer;
label lRedo;
var sURL, sPageWeb, sURLRedir: string;
    iRedo: integer;
    bBackup: boolean;
    sDataToPost: string;
begin

    Result := CNT_ERROR_USER;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;

    if FCurrentPlanete = nil then begin
       {$IFDEF DEBUG}
          DoDebug('ProceedRessourceCalcul - Aucune planète sélectionnée - LogIn non effectué peut-être');
       {$ENDIF}

       exit;
    end;


    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.pMenuLeft.GetLink(mliRessource);

    

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;



    // Obtient l'url
    sURL := FParsingPages.pRessources.FormAction;

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;

    //
    sDataToPost := FCurrentPlanete.cRessources.GetDonneesAPoster;
    if sDataToPost = '' then begin
       // erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Aucune données à poster (erreur)');
       {$ENDIF}

       Result := 1;
       exit;
    end;

    if FParsingPages.pRessources.SubmitPostAdd <> '' then begin
       sDataToPost := sDataToPost + '&' + FParsingPages.pRessources.SubmitPostAdd;

    end else begin
       // il y a obligatoirement le bouton de submit
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Bouton submit non trouvé');
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;

    //sDataToPost := sfcRemplace(sDataToPost, '100', '100, noob=77');
    //sDataToPost := sfcRemplace(sDataToPost, '100', '4294967316');



    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Post des données de calcul des ressources: ' + sURL);
    {$ENDIF}
    {$IFDEF DEBUG}
        DoDebug('ProceedRessourceCalcul - Données postées: ' + sDataToPost);
    {$ENDIF}

    sPageWeb := '';
    bBackup := FsockHTTP.FollowRelocation;
    FsockHTTP.FollowRelocation := False;
    sPageWeb := myGETorPOST_InTamponX(sURL, sDataToPost, FsockHTTP);
    FsockHTTP.FollowRelocation := bBackup;
    
    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Erreur dl');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SHOULD_RELOGIN;
          exit;
       end;

       goto lRedo;


    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedRessourceCalcul - Doit se relogger');
       {$ENDIF}

       Result := CNT_ERROR_MUST_RELOGIN;
       exit;
    end;

    // la page est censé correspondre à une redirection
    if (FsockHTTP.StatusCode >= 300) and (FsockHTTP.StatusCode < 400) then begin
       // c'est une redirection
       // extrait le lien de redirection
       sURLRedir := mcsExtractLocation(FsockHTTP.RcvdHeader);

       if sURLRedir = '' then begin
         {$IFDEF DEBUG}
             DoDebug('ProceedRessourceCalcul - Lien de redirection non trouvée - StatusCode: ' + IntToStr(FsockHTTP.StatusCode));
         {$ENDIF}
         Result := CNT_ERROR_FATAL;
         exit;
       end;

    end else begin

       sURLRedir := '';
       if FsockHTTP.StatusCode = 200 then begin
          sURLRedir := ExtractRedirRessourceURL(sPageWeb);
       end;

       if sURLRedir = '' then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedRessourceCalcul - Pas de redirection trouvée - StatusCode: ' + IntToStr(FsockHTTP.StatusCode));
          {$ENDIF}
          
          Result := CNT_ERROR_FATAL;
          exit;
       end;



    end;

    
    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);

    // Définit l'url entière
    sURL  := sHTML_Get_URL_Lien(sURL, sURLRedir);

    // télécharge la page de confirmation
    Result := ProceedUpdateRessource(true, false, sURL);

    if Result > 0 then begin
       FCurrentPlanete.ActionDateDernierCalculRessource := DateTimeToUnix(Now);
    end;
end;

function ExtractRedirRessourceURL(sPage: string): string;
var xPos: integer;
begin
   // La page correspond à:
   // <script>document.location.href='index.php?page=resources&session=238e59bffdf2&pc=1'</script>

   Result := '';

   if pos('document.location.href', sPage) < 1 then begin
      // il n'y a pas de javascript
      exit;
   end;

   xPos := pos('''index.php', sPage);

   if xPos < 1 then begin
      exit;
   end;

   // supprime aussi le '
   System.Delete(sPage, 1, xPos);

   xPos := pos('''', sPage);

   if xPos < 1 then begin
      exit;
   end;

   Result := copy(sPage, 1, xPos - 1);


end;

function TPlayerGestion.ProceedUpdateRessource(bModifyAllList: boolean; bCalculRessources: boolean; FromThisURL: string = ''): integer;
label lRedo, lRedir;

var sURL, sPageWeb: string;
    //sList: TList;
    iRedo: integer;

    sURLRedir: string;
    sRedirState: TRessourceRedirState;
begin
    Result := CNT_ERROR_USER;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;

    if FCurrentPlanete = nil then begin
       {$IFDEF DEBUG}
          DoDebug('ProceedUpdateRessource - Aucune planète sélectionnée - LogIn non effectué peut-être');
       {$ENDIF}

       exit;
    end;


    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sURL := FParsingPages.pMenuLeft.GetLink(mliRessource);
    if FromThisURL <> '' then begin
       sURL := FromThisURL;
    end;

    if lowercase(copy(sURL, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Lien de la page incorrect: ' + sURL);
       {$ENDIF}

       Result := CNT_ERROR_FATAL;
       exit;
    end;

    iRedo := 0;
    sRedirState := trrsNeant;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page ressource: ' + sURL);
    {$ENDIF}

    sPageWeb := myGETorPOST_InTamponX(sURL, '', FsockHTTP);

    if (FsockHTTP.StatusCode >= 300) and (FsockHTTP.StatusCode < 400) then begin
       // on est face à une redirection

       if (sRedirState = trrsNeant) and (sRedirState <> trrsHandled) then begin
          sURLRedir := mcsExtractLocation(FsockHTTP.RcvdHeader);
          FCookies.ParseHeader(FsockHTTP.RcvdHeader);

          if sURLRedir = '' then begin
            {$IFDEF DEBUG}
                DoDebug('ProceedUpdateRessource - (x) Lien de redirection non trouvée - StatusCode: ' + IntToStr(FsockHTTP.StatusCode));
            {$ENDIF}
            Result := CNT_ERROR_FATAL;
            exit;
          end;

          sRedirState := trrsHTTP302;
          goto lRedir;

       end else begin
          // double redirection ???
          {$IFDEF DEBUG}
              DoDebug('ProceedUpdateRessource - Loop Erreur');
          {$ENDIF}

       end;

    end;

    

    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Erreur dl');
       {$ENDIF}


       if iRedo > 2 then begin
          Result := CNT_ERROR_SHOULD_RELOGIN;
          exit;
       end;

       goto lRedo;


    end else if sPageWeb = mcDL_MUST_RELOGIN then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Doit se relogger');
       {$ENDIF}

       Result := CNT_ERROR_MUST_RELOGIN;
       exit;
    end;


    //FParserRessource.DontFreePointeur := false;

   
    if FParsingPages.ParsingRessources(sPageWeb) = false then begin

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          Result := CNT_ERROR_MUST_RELOGIN;
       end else begin
          Result := CNT_ERROR_PARSING;
       end;



       if FParsingPages.IsValidPage = false then begin
          // erreur de socket

          if (sRedirState = trrsNeant) and (sRedirState <> trrsHandled) then begin
             // vérifie si ce n'est pas une redirection HTML
             sURLRedir := '';
             sURLRedir := ExtractRedirRessourceURL(sPageWeb);

             if length(sURLRedir) > 5 then begin
                // c'était une redirection html
                sRedirState := trrsHTML;
                goto lRedir;
             end;
          end;

          {$IFDEF DEBUG}
              DoDebug('ProceedUpdateRessource - Page invalide... Taille: ' + IntToStr(length(sPageWeb)));
          {$ENDIF}


          if iRedo > 2 then begin
             Result := CNT_ERROR_PARSING;

             if length(sPageWeb) > 10 then begin
                {$IFDEF DEBUGFILE_WHEN_ECHEC}
                   DebugWebPage(sPageWeb, CNT_DEBUGFILE_RESSOURCES);
                {$ENDIF}
             end;
             exit;
          end;

          goto lRedo;

       end;

       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateRessource - Le parsing a échoué');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
          DebugWebPage(sPageWeb, CNT_DEBUGFILE_RESSOURCES);
       {$ENDIF}

       exit;
    end;

    
lRedir:
    if (sRedirState <> trrsNeant) and (sRedirState <> trrsHandled) then begin
       // aucune page ressources n'a été téléchargé

       sRedirState := trrsHandled;

       // définit la nouvelle url
       sURL  := sHTML_Get_URL_Lien(sURL, sURLRedir);

       iRedo := 0;

       goto lRedo;

    end;




    // ATTENTION: C'est après le parsing que l'on définit l'url de la page
    // sinon les liens vers les autres planète ne seront pas complet
    //FParserRessource.SetURLOfThisPage(sURL);
    FParsingPages.SetURLOfThisPage(sURL);

    
    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);



    // Récupère la liste
    //sList := FParsingPages.pRessources.RessourcesList;


    Result := FParsingPages.pRessources.RessourcesList.Count;


    if FParsingPages.pRessources.RessourcesList.Count > 0 then begin
       // Le parsing a réussi
       // On supprime les anciens éléments
       FCurrentPlanete.cRessources.ClearAndFree;

       // Ajoute les nouveaux éléments
       //InjectTList(sList, FCurrentPlanete.cRessources);
       FParsingPages.pRessources.RessourcesList.DupliqueTo(FCurrentPlanete.cRessources);



       if bModifyAllList then begin
          // Duplique la liste (ne se contente pas d'injecter les pointeurs)
          //FCurrentPlanete.cRessourcesToSet.ClearAndFree;
          //DupliqueTList(sList, FCurrentPlanete.cRessourcesToSet);
       end;


       // Les pointeurs ont été transféré, on vide la liste
       //sList.Clear;

       if bCalculRessources then begin
          // calcul les ressources
          Result := ProceedRessourceCalcul;
       end;


    end;


    // Met à jour la quantité de ressources
    FCurrentPlanete.FLastRessources     := FParsingPages.pHeader.CurrRessource;
    FCurrentPlanete.FLastRessourcesDate := DateTimeToUnix(Now);

    //FLastPageWebDL := FParserRessource;

end;


function TPlayerGestion.ProceedGalaxieScan(cDatabase: TCollectionGalaxiePlanete; Galaxie, SystemStart, SystemEnd: integer; UpdatePlusAncienQueCetteDate: int64): integer;
label lRedo;
var sPageWeb, sHTTP: string;
    iRedo, i: integer;

    DataToPost: string;

    currSystemSolaire: integer;
    currCoordAll: TPlanetLocation;
    currFistPlanetePos: PGalaxiePlanete;

    bMethodInc: boolean;

    iNbPassageBoucle: integer;

    DureeSleep: integer;

begin

    Result := CNT_ERROR_USER;
    FProcRecolteArret := false;

    if FInLogin then exit;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;


    if FCurrentPlanete = nil then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Aucune planète sélectionnée - LogIn non effectué peut-être');
       {$ENDIF}

       exit;
    end;



    if (SystemStart < 1) or (SystemEnd < 1) or (SystemStart > 499) or (SystemEnd > 499)  then begin
       // On déclenche une erreur au lieu de le corriger automatiquement
       Result := CNT_ERROR_USER;
       exit;
    end;

    FJobOccupation := jobpOccupe;


    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sHTTP := FParsingPages.pMenuLeft.GetLink(mliGalaxie);


    if lowercase(copy(sHTTP, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
            DoDebug('ProceedGalaxieScan - Lien de la page galaxie incorrect: ' + sHTTP);
       {$ENDIF}

       FJobOccupation := jobpAucun;
       Result := CNT_ERROR_FATAL;
       exit;
    end;


    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page galaxie: ' + sHTTP);
    {$ENDIF}

    sPageWeb := myGETorPOST_InTamponX(sHTTP, '', FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Erreur dl');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SHOULD_RELOGIN;
          FJobOccupation := jobpAucun;
          exit;
       end;

       goto lRedo;

    end else if length(sPageWeb) < 200 then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Page trop petite');
       {$ENDIF}

       Result := CNT_ERROR_SHOULD_RELOGIN;
       exit;
    end;


    // ON N'OUBLIE PAS LES EVENTUELS NOUVEAUX COOKIES
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);


    // Parse la page
    // Puis se positionne sur le bon endroit de l'univers


    cParsing.pGalaxie.DontAddPointeur := true;
    if cParsing.ParsingGalaxie(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedGalaxieScan - Le parsing a échoué');
       {$ENDIF}

       Result := CNT_ERROR_SHOULD_RELOGIN;
       FJobOccupation := jobpAucun;
       exit;
    end;

    // rétablie la propriété
    cParsing.pGalaxie.DontAddPointeur := false;

    cParsing.SetURLOfThisPage(sHTTP);

    // sHTTP est la même url pour chaque page web de la galaxie
    // session=4dcf4e4c884a&xr=dr&p1=3&p2=19

    // si on clique sur montrer, on a donc:
    // session=4dcf4e4c884a&p1=3&p2=19


    // session: la session
    // p1 : galaxie
    // p2 : système solaire

(*
   <form action="galaxy.php?session=<session> method=post id=galaxy_form>

    // la session
    <input type="hidden" name="session" value="00000000">

    // champs dont le nom 'id' sera modifier par le première paramètre de galaxy_submit()
    // sa valeur est-elle par contre toujours "dr" ?
    <input type="hidden" id="auto" value="dr">


    // la galaxie
          <td class="l"><input type="button" name="galaxyLeft" value="<-" onClick="galaxy_submit('galaxyLeft')"></td>
          <td class="l"><input type="text" name="galaxy" value="3" size="5" maxlength="3" tabindex="1">
          <td class="l"><input type="button" name="galaxyRight" value="->" onClick="galaxy_submit('galaxyRight')"></td>

    // le système solaire
          <td class="l"><input type="button" name="systemLeft" value="<-" onClick="galaxy_submit('systemLeft')"></td>
          <td class="l"><input type="text" name="system" value="3" size="5" maxlength="3" tabindex="2">
          <td class="l"><input type="button" name="systemRight" value="->" onClick="galaxy_submit('systemRight')"></td>

    // Le bouton montrer
    <td colspan="2" align="center"> <input type="submit" value="Afficher"></td>
*)

    // Fait en sorte que l'on parcours la galaxie de manière croissante
    // SystemStart, SystemEnd

    // Prépare la chaine de format
    // La galaxie ne change pas, il y a que le système solaire qui change, il suffit
    // de l'ajouter à la fin de la chaine
    DataToPost := 'session=' + cParsing.pGalaxie.SessionKey + '&galaxy=' + IntToStr(Galaxie) + '&system=';

    if length(cParsing.pGalaxie.SessionKey) < 5 then begin
       // Session key invalide
       Result := CNT_ERROR_FATAL; 
       FJobOccupation := jobpAucun;
       exit;
    end;




    {$IFDEF DEBUG}
       DoDebug('SessionKey: ' + cParsing.pGalaxie.SessionKey);
       DoDebug('Galaxie Initiale: ' + IntToStr(cParsing.pGalaxie.Galaxie));
       DoDebug('Système Initial: ' + IntToStr(cParsing.pGalaxie.SystemSolaire));
       DoDebug('Galaxie à scanner: ' + IntToStr(Galaxie));
    {$ENDIF}

    // ceci permet de récupère la date de dernière mise à jour de la première
    // planète d'un système solaire, et ainsi déterminer si il faut le mettre
    // à jour ou pas
    currCoordAll.Galaxie :=  Galaxie;
    currCoordAll.Position := 1;

    currSystemSolaire := SystemStart;

    if SystemStart > SystemEnd then
       // il faudra décrémenter
       bMethodInc := false
    else
       // sinon incrémenter
       bMethodInc := true;



    // On effectue la première incrémentation/decrementation en début de boucle
    // on fait en sorte que l'on tombe sur le système de départ au premier passage dans la boucle
    if bMethodInc then
       Dec(currSystemSolaire)
    else
       Inc(currSystemSolaire);


    iNbPassageBoucle := 0;


    // Met à jour le lien de référence
    FsockHTTP.Reference := sHTTP;

    Result := 1;


     if Conf.HumanGalaxieScanEnable then begin

        DoStatusGalaxie('Humanisation activée');
        DoStatusGalaxie(format('-> Intervalle: %d à %d', [Conf.HumanGalaxieScanDuree, Conf.HumanGalaxieScanDuree + Conf.HumanGalaxieScanAleatoire]));
     end;


    //
    // Debut de la boucle
    //

    repeat

        if bMethodInc then
           Inc(currSystemSolaire)
        else
           Dec(currSystemSolaire);

        // On affiche que le numéro du système, c'est à la procédure que l'on appelle de rajouter
        // d'autre message
        DoStatusGalaxie(IntToStr(currSystemSolaire));

        currCoordAll.SystemSolaire := currSystemSolaire;

        currFistPlanetePos := cDatabase.Get_Pointeur(currCoordAll);

        if currFistPlanetePos <> nil then begin
           // ce système a déjà été sondé
           if currFistPlanetePos.Date > UpdatePlusAncienQueCetteDate then begin
              // inutile de mettre à jour ce système
              DoStatusGalaxie('Inutile de mettre à jour ce système: ' + IntToStr(currSystemSolaire) + ' - Dernier scan: ' + DateTimeToStr(UnixToDateTime(currFistPlanetePos.Date)));

              // Le continue effectue quand même le test de fin de boucle avant de revenir au début
              Continue;
           end;

        end;

        // Télécharge la page web
        sPageWeb := myGETorPOST_InTamponX(sHTTP, DataToPost + IntToStr(currSystemSolaire), FsockHTTP);


        if cParsing.ParsingGalaxie(sPageWeb) = false then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedGalaxieScan - Le parsing a échoué, on retente: ' + DataToPost + IntToStr(currSystemSolaire));

              DoDebug(sPageWeb);
           {$ENDIF}



           
           Sleep(400);
           Application.ProcessMessages;
           Sleep(400);

           // reTélécharge la page web
           sPageWeb := myGETorPOST_InTamponX(sHTTP, DataToPost + IntToStr(currSystemSolaire), FsockHTTP);

           if cParsing.ParsingGalaxie(sPageWeb) = false then begin
              {$IFDEF DEBUG}
                 DoDebug('ProceedGalaxieScan - Le parsing a encore échoué: ' + DataToPost + IntToStr(currSystemSolaire));

                 DoDebug(sPageWeb);
              {$ENDIF}

              Result := CNT_ERROR_SHOULD_RELOGIN;
              FJobOccupation := jobpAucun;
              exit;
           end;

        end;

        cParsing.SetURLOfThisPage(sHTTP);

        // ON N'OUBLIE PAS LES EVENTUELS NOUVEAUX COOKIES
        FCookies.ParseHeader(FsockHTTP.RcvdHeader);


        {$IFDEF DEBUG}
             DoDebug('ProceedGalaxieScan - Injection: ' +  IntToStr(cParsing.pGalaxie.ListPlanete.Count) + ' - ' + cParsing.pGalaxie.ListPlanete.GetFirstItemCoord);

             if cParsing.pGalaxie.ListPlanete.Count < 15 then begin
                // Erreur probable...
                DoDebug('ProceedGalaxieScan - Erreur, élément dans le système solaire: ' + IntToStr(cParsing.pGalaxie.ListPlanete.Count));
             end;
        {$ENDIF}



        // Importe dans la base de données
        cDatabase.CopyFromList(cParsing.pGalaxie.ListPlanete);

        {$IFDEF DEBUG}
             DoDebug('ProceedGalaxieScan - Quantité après injection: ' +  IntToStr(cDatabase.Count));
        {$ENDIF}


        Sleep(100);
        Application.ProcessMessages;
        Sleep(100);

        Inc(iNbPassageBoucle);
        if iNbPassageBoucle > 520 then begin
           Result := CNT_ERROR_FATAL; 
           FJobOccupation := jobpAucun;
           exit;
        end;


        if FProcRecolteArret then begin
           {$IFDEF DEBUG}
               DoDebug('ProceedGalaxieScan - Arret demandé par l''utilisateur');
           {$ENDIF}

           Result := -1; 
           FJobOccupation := jobpAucun;
           break;
        end;

        if Conf.HumanGalaxieScanEnable then begin
           Randomize;
           DureeSleep := Conf.HumanGalaxieScanDuree + Random(Conf.HumanGalaxieScanAleatoire);
           DureeSleep := DureeSleep * 1000;
           DoSleep(DureeSleep);
        end;






    until currSystemSolaire = SystemEnd;

    FJobOccupation := jobpAucun;

end;

function TPlayerGestion.ProceedCollectStatsPlayer(cDatabase: TCollectionPlayerStats; dbType: TStatsType): integer;
label lRedo;
var sPageWeb, sHTTP: string;
    sList: TList;
    iRedo, i: integer;
    sLinkKeep: array[1..15] of string;
begin


    Result := CNT_ERROR_USER;

    if FInLogin then exit;
    
    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;


    if FCurrentPlanete = nil then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Aucune planète sélectionnée - LogIn non effectué peut-être');
       {$ENDIF}

       exit;
    end;

    FJobOccupation := jobpOccupe;

    FProcRecolteArret := false;


    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;

    // Obtient l'url à partir de l'id
    sHTTP := FParsingPages.pMenuLeft.GetLink(mliStatistiques);

    if lowercase(copy(sHTTP, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
            DoDebug('ProceedCollectStatsPlayer - Lien de la page statistiques incorrect: ' + sHTTP);
       {$ENDIF}

       FJobOccupation := jobpAucun;
       Result := CNT_ERROR_FATAL;
       exit;
    end;



    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('Téléchargement page statistiques: ' + sHTTP);
    {$ENDIF}

    sPageWeb := myGETorPOST_InTamponX(sHTTP, '', FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Erreur dl');
       {$ENDIF}

       if iRedo > 2 then begin
          Result := CNT_ERROR_SHOULD_RELOGIN;
          FJobOccupation := jobpAucun;
          exit;
       end;

       goto lRedo;

    end else if length(sPageWeb) < 200 then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Page trop petite');
       {$ENDIF}

       Result := CNT_ERROR_SHOULD_RELOGIN;
       FJobOccupation := jobpAucun;
       exit;
    end;



    cParsing.pStats.TypeStats := dbType;

    cParsing.pStats.DontAddToList := true;


    
    if cParsing.ParsingStats(sPageWeb) = false then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedCollectStatsPlayer - Le parsing a échoué');
       {$ENDIF}

       Result := CNT_ERROR_SHOULD_RELOGIN;
       FJobOccupation := jobpAucun;
       exit;
    end;
    cParsing.pStats.DontAddToList := false;

    // ON N'OUBLIE PAS LES EVENTUELS NOUVEAUX COOKIES
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);


    cParsing.SetURLOfThisPage(sHTTP);

    // On importe pas, car on va importer plus loin, cela évite de trier en plus
    // et en plus on peut aussi vouloir les flottes ou la recherche au lieu des points totaux
    //cDatabase.ImportList(FParserStats.Stats);


    for i := 1 to 15 do begin
       // sauvegarde les données à poster
       sLinkKeep[i] := cParsing.pStats.GetLinkTop(i);

    (*
       if lowercase(copy(sLinkKeep[i], 1, 4)) <> 'http' then begin
          // Erreur
          DoDebug('ProceedCollectStatsPlayer - dLien de la page statistiques incorrect: ' + sLinkKeep[i]);
          Result := CNT_ERROR_FATAL;
          exit;
       end;
*)

    end;

    
    Result := 1;

    for i := 1 to 15 do begin
       // Le lien de référence est la page en cours, plus celle du menu
       FsockHTTP.Reference := FsockHTTP.URL;

       // On n'oublie pas les cookies, car ils peuvent avoir changés
       FsockHTTP.Cookie    := FCookies.GetCookieData;

       // Et on télécharge la page
       {$IFDEF DEBUG}
          DoDebug('Téléchargement page statistiques: ' + IntToStr(i));
       {$ENDIF}

       sPageWeb := myGETorPOST_InTamponX(sHTTP, sLinkKeep[i],  FsockHTTP);

       if sPageWeb = modDL_ERREUR_DL_STR then begin
          {$IFDEF DEBUG}
             DoDebug('ProceedCollectStatsPlayer - Erreur dl b');
          {$ENDIF}

          // Retélécharge la même page web
          DoSleep(750);
          sPageWeb := myGETorPOST_InTamponX(sHTTP, sLinkKeep[i], FsockHTTP);

       end else if sPageWeb = mcDL_MUST_RELOGIN then begin
          {$IFDEF DEBUG}
             DoDebug('ProceedCollectStatsPlayer - Doit se relogger');
          {$ENDIF}

          Result := CNT_ERROR_MUST_RELOGIN;
          FJobOccupation := jobpAucun;
          exit;
       end;

       if sPageWeb = modDL_ERREUR_DL_STR then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedCollectStatsPlayer - Erreur dl - Skipping');
          {$ENDIF}

          // il faut indiquer que l'on a skippé une page web
          Result := -1;

          DoSleep(500);
          Continue;
       end else if length(sPageWeb) < 200 then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedCollectStatsPlayer - Page trop petite (b)');
          {$ENDIF}

          Result := CNT_ERROR_SHOULD_RELOGIN;
          FJobOccupation := jobpAucun;
          exit;
       end;

       if cParsing.ParsingStats(sPageWeb) = false then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedCollectStatsPlayer - Le parsing a échoué (b)');
          {$ENDIF}

          Result := CNT_ERROR_SHOULD_RELOGIN;
          FJobOccupation := jobpAucun;
          exit;
       end;

       cParsing.SetURLOfThisPage(sHTTP);


       // ON N'OUBLIE PAS LES EVENTUELS NOUVEAUX COOKIES
       FCookies.ParseHeader(FsockHTTP.RcvdHeader);



       cDatabase.ImportList(cParsing.pStats.Stats);

       if FProcRecolteArret then begin
          {$IFDEF DEBUG}
              DoDebug('ProceedCollectStatsPlayer - Arret demandé par l''utilisateur');
          {$ENDIF}

          Result := -1;
          break;
       end;

    end;

    FJobOccupation := jobpAucun;
    

end;



function TPlayerGestion.ProceedUpdateElement(IdFromMenu: TMenuLinkID; bDoUpdateItem: boolean = true): integer;
label lRedo, lMakeErr;
var sPageWeb, sHTTP: string;
    //sList: TList;
    iRedo: integer;

    {$IFDEF DEBUGFILE_FLAG}
       sDebugFile: string;
    {$ENDIF}
begin
    // On doit mettre à jour la liste des batiments constructible
    // pour la planète en cours

    Result := CNT_ERROR_USER;

    if bDoUpdateItem = false then begin
       Result := CNT_ERROR_USER - 1;

    end;

    if FInLogin then exit;

    if FsockHTTP.State <> httpReady then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Composant HTTP non prêt');
       {$ENDIF}

       exit;
    end;

    if FJobOccupation <> jobpAucun then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Un autre job est déjà en cours d''exécution');
       {$ENDIF}

       exit;
    end;


    if FCurrentPlanete = nil then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Aucune planète sélectionnée - LogIn non effectué peut-être');
       {$ENDIF}

       exit;
    end;

    FJobOccupation := jobpOccupe;


    // On télécharge la page web
    // celle-ci provient suite à un clique dans le menu à gauche
    FsockHTTP.Reference := FParsingPages.LastPageURLMenu;

    // On n'oublie pas les cookies
    FsockHTTP.Cookie    := FCookies.GetCookieData;


    // Obtient l'url à partir de l'id
    sHTTP := FParsingPages.pMenuLeft.GetLink(IdFromMenu);



    if lowercase(copy(sHTTP, 1, 4)) <> 'http' then begin
       // Erreur
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Lien de la page "élément" incorrect: ' + sHTTP);
       {$ENDIF}

       FJobOccupation := jobpAucun;
       Result := CNT_ERROR_FATAL;
       exit;
    end;

    
    // Avant de télécharger la page, on vérifie que l'id est bien correct  
    case IdFromMenu of
        mliBatiments      : FParsingPages.pElements.GidType := tgidBatiment;
        mliRecherche      : FParsingPages.pElements.GidType := tgidRecherche;
        mliChantierSpatial: FParsingPages.pElements.GidType := tgidVaisseau;
        mliDefense        : FParsingPages.pElements.GidType := tgidDefense;
        else begin
                  {$IFDEF DEBUG}
                      DoDebug('ProceedUpdateElement - Id invalide: ' + IntToStr(Ord(IdFromMenu)) + ' Lien:' + sHTTP);
                  {$ENDIF}

                  Result := CNT_ERROR_FATAL;
                  FJobOccupation := jobpAucun;
                  exit;
             end;
    end;

    iRedo := 0;
lRedo:
    Inc(iRedo);

    // Et on télécharge la page
    {$IFDEF DEBUG}
        DoDebug('ProceedUpdateElement - Téléchargement page élément: ' + sHTTP);
    {$ENDIF}

    sPageWeb := myGETorPOST_InTamponX(sHTTP, '', FsockHTTP);


    if sPageWeb = modDL_ERREUR_DL_STR then begin
       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Erreur dl');
       {$ENDIF}

lMakeErr:

       if iRedo > 5 then begin
          Result := CNT_ERROR_SOCKET;
          FJobOccupation := jobpAucun;
          exit;
       end;
       DoSleep(200);
       Application.ProcessMessages;
       DoSleep(200);
       DoSleep(800);

       goto lRedo;


    end else if sPageWeb = mcDL_MUST_RELOGIN  then begin

       // la session à expirer
       Result := CNT_ERROR_MUST_RELOGIN;
       FJobOccupation := jobpAucun;

       {$IFDEF DEBUG}
           DoDebug('ProceedUpdateElement - Session expiré, doit se relogger');
       {$ENDIF}
       exit;


       //goto lMakeErr;

       //Result := CNT_ERROR_SHOULD_RELOGIN;
       //FJobOccupation := jobpAucun;
       //exit;
    end;

    // Ne libére pas les pointeurs actuels, car on va les effacer nous
    // même si le parsing reussi, cependant, les anciens éléments (les pointeurs seulement)
    // sont supprimés de la liste
    // UPDATE: Impossible de dire si les pointeurs doivent être supprimer (libérer)
    //         ou pas puisque tout ceci est déterminé par ce que l'on en aura fait
    //         après le parsing
    // La valeur de cette variable est alors définit à la fin de la fonction
    // et elle sera exploité lors de la prochaine exécution de la fonction
    //FParserElement.DontFreePointeur := true;


   // FParserElement.SetURLOfThisPage(sHTTP);

    {$IFDEF DEBUGFILE_FLAG}
       case IdFromMenu of
           mliBatiments      : sDebugFile := CNT_DEBUGFILE_ELEMENT_BATIMENTS;
           mliRecherche      : sDebugFile := CNT_DEBUGFILE_ELEMENT_RECHERCHE;
           mliChantierSpatial: sDebugFile := CNT_DEBUGFILE_ELEMENT_CHANTIER_SPATIAL;
           mliDefense        : sDebugFile := CNT_DEBUGFILE_ELEMENT_DEFENSE;
           else                      sDebugFile := CNT_DEBUGFILE_ELEMENT_UNKNOW;
       end;
    {$ENDIF}



    // On extrait les données de la page
    if FParsingPages.ParsingElements(sPageWeb) = false then begin
       {$IFDEF DEBUG}
            DoDebug('ProceedUpdateElement - Le parsing a échoué (Size: ' + IntToStr(length(sPageWeb)) + ')');
       {$ENDIF}

       {$IFDEF DEBUGFILE_WHEN_ECHEC}
          DebugWebPage(sPageWeb, sDebugFile);
       {$ENDIF}

       if mpcPageWebIsSessionExpireDBProblem(sPageWeb) then begin
          // la session à expirer
          Result := CNT_ERROR_MUST_RELOGIN;

          {$IFDEF DEBUG}
              DoDebug('ProceedUpdateElement - Session expiré, doit se relogger');
          {$ENDIF}
          FJobOccupation := jobpAucun;
          exit;
       end;



       if (FParsingPages.IsValidPage = false) or (length(sPageWeb) < 20) then begin
          // socket error
          {$IFDEF DEBUG}
              DoDebug('ProceedUpdateElement - Page non valide -> Socket error (serveur lag?)');
          {$ENDIF}
          Result := CNT_ERROR_SOCKET;

       end else begin
          Result := CNT_ERROR_PARSING;
       end;





       FJobOccupation := jobpAucun;
       exit;

    end else begin

       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
          DebugWebPage(sPageWeb, sDebugFile);
       {$ENDIF}
    end;

    // Gère les cookies
    FCookies.ParseHeader(FsockHTTP.RcvdHeader);



     // ATTENTION: C'est après le parsing que l'on définit l'url de la page
     // sinon les liens vers les autres planète ne seront pas complet

    FParsingPages.SetURLOfThisPage(sHTTP);


    CheckCurrentPlanetFromHeader();




    // Récupère la liste
    //sList := FParserElement.Valeurs;

    Result := FParsingPages.pElements.ElementsList.Count;


    if (FParsingPages.pElements.ElementsList.Count > 0) then begin
       // Le parsing a réussit

       if bDoUpdateItem then begin
          // On supprime les anciens éléments de la planète
          FCurrentPlanete.cElements.DeleteThisType(FParsingPages.pElements.GidType);



          // Ajoute les nouveaux éléments
          // seulement les pointeurs
          InjectTList(FParsingPages.pElements.ElementsList, FCurrentPlanete.cElements);

          // et les supprimes de la liste pour que les données pointées ne soient
          // pas libérées
          FParsingPages.pElements.ElementsList.Clear;


          // Les éléments ont été sauvegardé, lors du prochain parsing, il ne
          // faudra pas les libérer
          //FParserElement.DontFreePointeur := true;


          // les éléments sont maintenant géré par la classe des "planètes"
          // on peut les supprimer de la classe de parsing
          //FParserElement.Valeurs.Clear;

    {$IFDEF DEBUG}
      //  DoDebug('ProceedUpdateElement - Injection: ' + IntToStr(Result));
    {$ENDIF}


          // TODO: Au lieu de trier bêtement les pointeurs, on devrait
          // appeller un CallBack pour raffraichir les éléments de la
          // grille
          FCurrentPlanete.cElements.Trie;


          if IdFromMenu = mliBatiments then begin
             if FCurrentPlanete.cElements.SomethingOfThisTypeIsInConstruction(tgidBatiment) = false then begin
                // on peut construire des bâtiments
                FCurrentPlanete.ActionDateFinBatiment := DateTimeToUnix(Now) - 1;
             end;
          end;

       end else begin
          // on pourra libérer les items lors du prochain parsing
          // update: False est mis par défaut à la fin du parsing
          // ceci dans le but de forcer l'assignation à True
          // lorsque l'on utilise InjectTList pour copier les pointeurs
          //FParserElement.D0ntFreePointeur := false;

       end;

    end else begin
       // Il se peut en effet qu'il n'y ai aucun élément, comme par exemple
       // pour la defense, ou encore la recherche et le chantier spatial

       // on pourra libérer les items lors du prochain parsing
       // update: False est mis par défaut à la fin du parsing
       // ceci dans le but de forcer l'assignation à True
       // lorsque l'on utilise InjectTList pour copier les pointeurs
       //FParserElement.D0ntFreePointeur := false;



       if FParsingPages.IsValidPage = false then begin
          // En tete invalide, le parsing a donc échoué
          Result := CNT_ERROR_PARSING;
          FJobOccupation := jobpAucun;
          exit;
       end;

       Result := 0;

    end;




    if FParsingPages.pHeader.ExistOfficier then begin
       {$IFDEF OFFICIER_OK}
           if AllowToWorkWithOfficier = false then begin
              // ne doit pas fonctionner avec les officiers
              Result := CNT_ERROR_PARSING;
           end;
       {$ELSE}
           // pas d'officier
           Result := CNT_ERROR_PARSING;
       {$ENDIF}
    end;




    // Met à jour la quantité de ressources
    FCurrentPlanete.FLastRessources     := FParsingPages.pHeader.CurrRessource;
    FCurrentPlanete.FLastRessourcesDate := DateTimeToUnix(Now);

    //FLastPageWebDL := FParserElement;
    FJobOccupation := jobpAucun;

end;



function TPlayerGestion.ProceedLogin: integer;
label lRedo1Post, lMakeErr1Post, lRedo2Frame, lMakeErr2Frame;
label lRedoFrameGaucheMenu, lMakeErrFrameGaucheMenu, lRedoFrameApercu4, lMakeErrFrameApercu4;
label lLoginOnGameServeur, lLoginOk, lParsingFrameOK, lRelocationFound;

var sPageWeb, sPageWebAccueilLogin: string;
    sHTTP: string;
    iRedo: integer;
    sDataToPost: string;
    sRelocation, sTmp: string;

    FStream: TFileStream;
begin

     Lock;

     sPageWebAccueilLogin := '';

     if FInLogin then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Déjà en cours de login');
        {$ENDIF}

        Result := CNT_LOGIN_ERROR_DEJAENCOURS;
        Unlock;
        exit;
     end;

     if FsockHTTP.State <> httpReady then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Socket non pret');
        {$ENDIF}
        Result := CNT_LOGIN_ERROR_SOCKETNONPRET;
        Unlock;
        exit;
     end;

     FPasswordIsInvalid := false;


     FInLogin := true;
     Unlock;

     Result := CNT_LOGIN_ERROR;

     FCookies.Clear;


     if (Conf.Pseudo = '') or (Conf.Password = '') then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Username ou Password non définit');
        {$ENDIF}
        FInLogin := false;
        exit;
     end;


     {$IFDEF DEBUG}
         DoDebug('ProceedLogin - Téléchargement page de login');
     {$ENDIF}

     (*
     if FLoginDirectOnGameServeur then begin

        if lowercase(copy(FLoginDirectURLServeur, 1, 4)) <> 'http' then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedLogin - DirectLogin -> Adresse de serveur de jeu invalide');
           {$ENDIF}
           FInLogin := false;
           exit;
        end;

        // pour le lien de reference:
        if lowercase(copy(FLogingUniversListPage, 1, 4)) <> 'http' then begin
           {$IFDEF DEBUG}
              DoDebug('ProceedLogin - DirectLogin -> Adresse de login invalide (pour le lien de reference)');
           {$ENDIF}
           FInLogin := false;
           exit;
        end;

        FsockHTTP.URL := FLogingUniversListPage;
        sHTTP         := FLoginDirectURLServeur;


        // Données à poster:
        sDataToPost := 'login=%s&password=%s&x=%d&y=%d';

           {$IFDEF DEBUG}
              DoDebug('ProceedLogin - DirectLogin -> Non supporte');
           {$ENDIF}
           FInLogin := false;
           exit;


        goto lLoginOnGameServeur;
     end;
     *)



     if lowercase(copy(FLogingUniversListPageReferenceLink, 1, 4)) <> 'http' then begin
        // erreur
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Lien de reference invalide, redefinit comme vide');
        {$ENDIF}

        FLogingUniversListPageReferenceLink := '';
     end;


    // General
    FCurrentPlanete := nil;

    // Met à jour la configuration avec la configuration pour les rares exceptions
    // où le ne peut pas utiliser les propriétés de Conf (par exemple pour l'évacuation)
    UpdateInternalFromConf;



    // Parametre du socket
    FsockHTTP.Agent          := Conf.NavAgent;
    FsockHTTP.AcceptLanguage := Conf.NavAcceptLanguage;
    FsockHTTP.Accept         := Conf.NavAccept;



    FsockHTTP.ProxyUsername := '';
    FsockHTTP.ProxyPassword := '';


    if Conf.ProxyActive then begin
       FsockHTTP.Proxy     := Conf.ProxyHostname;
       FsockHTTP.ProxyPort := IntToStr(Conf.ProxyPort);

       if Conf.ProxyIdentActive then begin
          FsockHTTP.ProxyUsername := Conf.ProxyUsername;
          FsockHTTP.ProxyPassword := Conf.ProxyPassword;
       end;

    end else begin
       FsockHTTP.Proxy     := '';
       FsockHTTP.ProxyPort := '';
    end;



     FsockHTTP.Reference := FLogingUniversListPageReferenceLink;
     FsockHTTP.Cookie := '';


     //sPageWeb := myGETorPOST_InTamponX('http://ogame170.de/portal/?lang=fr', '', FsockHTTP);
                                    //    http://ogame142.de/portal/?lang=fr







     if lowercase(copy(FLogingUniversListPage, 1, 4)) <> 'http' then begin
        // erreur
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Page de login des univers non definit ou invalide');
        {$ENDIF}

        Result := CNT_LOGIN_ERROR_DLFORMULAIRE_ECHEC;
        FInLogin := false;

        exit;
     end;


     if LoginUseLocalWebPage then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Telechargement: Utilisation page locale');
        {$ENDIF}

        sPageWeb := sfcRemplace(LoginLocalWebPage, '<<timestamp>>', DateTimeToUnix(Now) - 1800);


     
     end else begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Telechargement: ' + FLogingUniversListPage);
        {$ENDIF}

        sPageWeb := myGETorPOST_InTamponX(FLogingUniversListPage, '', FsockHTTP);
        sPageWebAccueilLogin := sPageWeb;
     end;



     FParserGetLogIn.Username := Conf.Pseudo;
     FParserGetLogIn.Password := Conf.Password;
     FParserGetLogIn.Univers  := Conf.Univers;

     if FSpecialLogin then begin
        FParserGetLogIn.NoMouseClick := true;
        FParserGetLogIn.SpecialLoginWithValidAction := true;
     end;

     if sPageWeb = modDL_ERREUR_DL_STR then begin
        // Erreur de socket
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - GetLogIn Echec (téléchargement du formulaire de login) Socket Error (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        Result := CNT_LOGIN_ERROR_DLFORMULAIRE_ECHEC;
        FInLogin := false;
        exit;

     end else if (length(sPageWeb) < 150) then begin
        // On ne réessaye pas de télécharger, les nouvels essais
        // se font dans la procédure appellante
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserGetLogIn Echec (téléchargement du formulaire de login) Page trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
           DoDebug(sPageWeb);
           DoDebug('ProceedLogin - FParserGetLogIn Echec (téléchargement du formulaire de login) Page trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        Result   := CNT_LOGIN_ERROR_DLFORMULAIRE_ECHEC;
        FInLogin := false;
        exit;

     end else if (FParserGetLogIn.ParseBuffer(sPageWeb) = false) then begin
        // Erreur de parsing, c'est déjà plus grave
        // on arrête l'auto relogin
        // ici on ne peut pas avoir l'erreur de ne pas être loggé car c'est la page de login

        Result   := CNT_ERROR_PARSING;
        FInLogin := false;
        exit;
     end;






     if FSpecialLogin then begin
        sHTTP := sHTML_Get_URL_Lien(FLogingUniversListPage, FParserGetLogIn.URLToPost);
     end else begin
        sHTTP := FParserGetLogIn.URLToPost;
     end;


     if lowercase(copy(sHTTP, 1, 4)) <> 'http' then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserGetLogIn Echec - URLToPost Invalide');
           DoDebug(sPageWeb);
           DoDebug('ProceedLogin - FParserGetLogIn Echec - URLToPost Invalide');
        {$ENDIF}


        Result := CNT_LOGIN_ERROR_URLFROMFORMULAIREINVALID;
        FInLogin := false;
        exit;
     end;


     // Fait une pause pour faire croire que l'on choisit l'univers
     DoSleep(1000);

     // ATTENTION: Ici on ne sauvegarde pas les cookies, car on n'est pas encore
     // sur le serveur de l'univers


     sDataToPost := FParserGetLogIn.DataToPost;

lLoginOnGameServeur:

     //////////////////////////////////////////////////////////////////////////
     // Se log en postant les données
     iRedo := 0;
lRedo1Post:

     Inc(iRedo);
     
     {$IFDEF DEBUG}
        DoDebug('ProceedLogin - Post des données du login: ' + sHTTP);
     {$ENDIF}

     // no fucking AUTO relocation
     FsockHTTP.FollowRelocation := false;
     sRelocation := '';


     FsockHTTP.Reference := FsockHTTP.URL;
     sPageWeb := myGETorPOST_InTamponX(sHTTP, sDataToPost, FsockHTTP);

     if sPageWeb = modDL_ERREUR_DL_STR then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Echec de téléchargement (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        goto lMakeErr1Post;

     end else if (length(sPageWeb) < 20) then begin
        sRelocation := mcsExtractLocation(FsockHTTP.RcvdHeader);

        if sRelocation <> '' then begin
           if pos('php?session', sRelocation) > 0 then begin
              // relocation vers une page valide du jeu (pas d'erreur de mot de passe ou autre)
              goto lRelocationFound;
           end;
        end;

        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Page web trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
            DoDebug(sPageWeb);
            DoDebug('---------- (fin des données)');
        {$ENDIF}


        if sRelocation <> '' then begin
           {$IFDEF DEBUG}
               DoDebug('ProceedLogin - Relocation: ' + sRelocation);
               DoDebug('ProceedLogin - C''est probablement une erreur de mot de passe');
           {$ENDIF}

           Result   := -1;
           FInLogin := false;
           exit;

        end else begin
           {$IFDEF DEBUG}
              DoDebugStrings(FsockHTTP.RcvdHeader);
           {$ENDIF}
        end;
        

        goto lMakeErr1Post;

     end else if (FParserAfterPostLogin.ParseBuffer(sPageWeb) = false) then begin

        // Update 21/07/2007
        // Dans certains univers (version 0.76d) la page de redirection correspond
        // à une relocation
        sRelocation := mcsExtractLocation(FsockHTTP.RcvdHeader);

        if sRelocation <> '' then begin
           // ok, c'était bien cela
           goto lRelocationFound;
        end;



        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - FParserAfterPostLogin Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
            DoDebug(sPageWeb);
            DoDebug('ProceedLogin - FParserAfterPostLogin Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}




        // il faut noter que parfois on obtient la stupide erreur:
        // "cliquez encore une fois"
        // que l'on ne peut pas forcément considéré comme une erreur de parsing...

        if pos('mail.php', sPageWeb) > 0 then begin
           // on propose de se réenvoyer le mot de passe
           // le mot de passe est donc invalide
           {$IFDEF DEBUG}
              DoDebug('ProceedLogin -> Utilisateur invalide (ou mot de passe incorrect)');
           {$ENDIF}
           Result := -1;


           // parfois les données sont mal postée (en proxy)
           if sockHttp.Proxy <> '' then begin
              // vérifie si l'username existe dans la page
              if pos('avec le nom ' + Conf.Pseudo + ' ', sPageWeb) > 0 then begin
                 FPasswordIsInvalid := true;
              end;

           end else begin
              FPasswordIsInvalid := true;
           end;

           exit;
        end;

        // le compte peut également être bloqué
        
        if pos('pranger.php', sPageWeb) > 0 then begin
           // Page web:
           // Ce compte est bloqué jusqu'au 2034-04-16 01:13:34 , pour plus d'informations, consultez le pilori en cliquant <a href=../pranger.php?PHPSESSID=dd8ce1dd51a041b46eba72a7035246f0> ici</a>. En cas de questions, prière de consulter <a href="http://ogame.fr/portal/?go=equipe&lang=fr">l'opérateur responsable pour votre univers</a><br>Attention : le blocage d'un compte ne résilie pas automatiquement un éventuel compte commandant associé à celui-ci, pensez à le résilier en cas de blocage définitif du compte.

           // Le compte est bloqué
           {$IFDEF DEBUG}
              DoDebug('ProceedLogin -> Le compte est bloqué');
           {$ENDIF}

            FPasswordIsInvalid := true;
            exit;
        end;





lMakeErr1Post:
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;
        DoSleep(600); Application.ProcessMessages;

        if iRedo > 3 then begin
           Result   := -1;
           FInLogin := false;
           exit;
        end;

        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Nouvelle tentative...');
        {$ENDIF}

        goto lRedo1Post;
     end;

lRelocationFound:
     FsockHTTP.FollowRelocation := true;


     // Obtient l'url entière
     if sRelocation <> '' then begin
        sHTTP := sHTML_Get_URL_Lien(sHTTP, sRelocation);
     end else begin
        sHTTP := sHTML_Get_URL_Lien(sHTTP, FParserAfterPostLogin.BasicURLRedirection);
     end;

     // Maintenant que l'on est sur le serveur, on peut gérer les cookies
     FCookies.ParseHeader(FsockHTTP.RcvdHeader);



(* Plus de page de définition des frames dans la version 0.77

     //////////////////////////////////////////////////////////////////////////
     // Télécharge la page de définition des frames
     iRedo := 0;
lRedo2Frame:

     Inc(iRedo);
     
     {$IFDEF DEBUG}
         DoDebug('ProceedLogin - Télécharge la page de définition des frames: ' + sHTTP);
     {$ENDIF}

     FsockHTTP.Reference := FsockHTTP.URL;
     FsockHTTP.Cookie := FCookies.GetCookieData;
     sPageWeb := myGETorPOST_InTamponX(sHTTP, '', FsockHTTP);

     if sPageWeb = modDL_ERREUR_DL_STR then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Echec de téléchargement (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        goto lMakeErr2Frame;

     end else if (length(sPageWeb) < 60) then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Page web trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
            DoDebug(sPageWeb);
            DoDebug('---------- (fin des données)');
        {$ENDIF}

lMakeErr2Frame:
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;

        if iRedo > 3 then begin
           Result   := -1;
           FInLogin := false;
           exit;
        end;

        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Nouvelle tentative...');
        {$ENDIF}

        goto lRedo2Frame;

     end else if (FParserFrame.ParseBuffer(sPageWeb) = false) then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserFrame Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
           DoDebug(sPageWeb);
           DoDebug('ProceedLogin - FParserFrame Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        // erreur de parsing

        Result   := CNT_ERROR_PARSING;
        FInLogin := false;
        exit;
     end;

lParsingFrameOK:


     // Gère les cookies
     FCookies.ParseHeader(FsockHTTP.RcvdHeader);

     // Sauvegarde le lien
     FParserFrame.URLOfThisFrame := sHTTP;

     // Définit l'url entière
     FParserMenu.URLOfThisFrame := sHTML_Get_URL_Lien(sHTTP, FParserFrame.BasicURLFrameLeft);

     // Définit l'url entière pour la page d'apperçu
     sHTTP  := sHTML_Get_URL_Lien(sHTTP, FParserFrame.BasicURLFrameRight);
     FParserApercu.URLOfThisPage := sHTTP;

*)



(* Plus de menu à gauche dans la version 0.77

{$IFNDEF NO_LEFT_MENU}

     //////////////////////////////////////////////////////////////////////////
     // Télécharge la frame de gauche (le menu)
     iRedo := 0;
lRedoFrameGaucheMenu:
     Inc(iRedo);

     {$IFDEF DEBUG}
         DoDebug('ProceedLogin - Télécharge le menu à gauche: ' + FParserMenu.URLOfThisFrame);
     {$ENDIF}

     FsockHTTP.Reference := FParserFrame.URLOfThisFrame;
     FsockHTTP.Cookie := FCookies.GetCookieData;
     sPageWeb := myGETorPOST_InTamponX(FParserMenu.URLOfThisFrame, '', FsockHTTP);

     if sPageWeb = modDL_ERREUR_DL_STR then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Echec de téléchargement (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        goto lMakeErrFrameGaucheMenu;

     end else if sPageWeb = mcDL_MUST_RELOGIN then begin
        // on vient à peine de se logger et on a déjà cette erreur ?
        Result := -1;
        FInLogin := false;
        exit;

     end else if (length(sPageWeb) < 130) then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Page web trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
            DoDebug(sPageWeb);
            DoDebug('---------- (fin des données)');
        {$ENDIF}

lMakeErrFrameGaucheMenu:
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;
        DoSleep(200); Application.ProcessMessages;
        DoSleep(500); Application.ProcessMessages;

        if iRedo > 3 then begin
           Result   := -1;
           FInLogin := false;
           exit;
        end;

        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Nouvelle tentative...');
        {$ENDIF}

        goto lRedoFrameGaucheMenu;


     end else if  (FParserMenu.ParseBuffer(sPageWeb) = false) then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserMenu Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
           DoDebug(sPageWeb);
           DoDebug('ProceedLogin - FParserMenu Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}


        Result   := CNT_ERROR_PARSING;
        FInLogin := false;
        exit;
     end;

     // Définit le lien complet pour faciliter le téléchargement des pages
     FParserMenu.SetFullURLFromBase(FParserMenu.URLOfThisFrame);
     FDateMenuLoad := DateTimeToUnix(Now);

     FIsFuckingCompteCommandant := FParserMenu.IsCompteCommandant;
     if FIsFuckingCompteCommandant then begin
        {$IFDEF DEBUG}
            sTmp := _('ProceedLogin - Compte commandant de merde détecté... Toutes les fonctionnalités ne seront pas disponible ou ne fonctionneront pas bien');
            DoDebug('~~~~~~~~~');
            DoDebug(sTmp);
            DoDebug(sTmp);
            DoDebug(sTmp);
            DoDebug('~~~~~~~~~');
        {$ENDIF}
     end;




     DownloadMiscFiles(FParserMenu.URLToDownloadAsIgnore);



     // une fois que les liens complet ont été défini, on créé un backup
     FParserMenu.SaveToBackup;

     // Gère les cookies
     FCookies.ParseHeader(FsockHTTP.RcvdHeader);


{$ENDIF}
*)




     //////////////////////////////////////////////////////////////////////////
     // Télécharge l'aperçu

     // 0.77: le lien correspond à sHTTP
     FsockHTTP.Reference := FsockHTTP.URL;

     iRedo := LastDelimiter('/\', sHTTP);
     if iRedo < 2 then begin
        // impossible
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - URL de la page aperçu invalide');
        {$ENDIF}

        Result := -1;
        FInLogin := false;
        exit;
     end;
     FRemoteURLGameDir := copy(sHTTP, 1, iRedo);
     FSessionId := copy(sHTTP, iRedo + 1, maxint);

     // overview.php?session=0000000000
     iRedo := pos('session=', lowercase(FSessionId));
     if iRedo > 0 then begin
        System.Delete(FSessionId, 1, iRedo + length('session=') - 1);

        iRedo := pos('&', FSessionId);
        if iRedo > 0 then
           System.Delete(FSessionId, iRedo, maxint);

     end else begin
        FSessionId := '';
     end;

     iRedo := 0;
lRedoFrameApercu4:
     Inc(iRedo);

     //

     {$IFDEF DEBUG}
         DoDebug('ProceedLogin - Télécharge l''aperçu ' + sHTTP);
     {$ENDIF}

     // lorsqu'on override le referer dans la fonction ProceedUpdateApercu,
     // on override aussi l'url, celle-ci correspond alors à l'url actuellement
     // contenu dans la classe, on fait donc:
     //FParserApercu.URLOfThisPage := sHTTP;
     FParsingPages.pApercu.SetFullURLFromBase(sHTTP);

     if ProceedUpdateApercu(true) < 1 then begin
        // echec de login
        Result := -395;

        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Aperçu erreur');
        {$ENDIF}

        exit;
     end;


     DownloadMiscFiles(cParsing.pMenuLeft.URLToDownloadAsIgnore);

(*
     FsockHTTP.Reference := FParserFrame.URLOfThisFrame;
     FsockHTTP.Cookie := FCookies.GetCookieData;
     sPageWeb := myGETorPOST_InTamponX(FParserApercu.URLOfThisPage, '', FsockHTTP);




     if sPageWeb = modDL_ERREUR_DL_STR then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Echec de téléchargement (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

        goto lMakeErrFrameApercu4;

     end else if sPageWeb = mcDL_MUST_RELOGIN then begin
        // on vient à peine de se logger et on a déjà cette erreur ?
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Doit se relogger ? (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}
        Result := -1;
        FInLogin := false;
        exit;


     end else if (length(sPageWeb) < 150) then begin
        {$IFDEF DEBUG}
            DoDebug('ProceedLogin - Page web trop petite (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
            DoDebug(sPageWeb);
            DoDebug('---------- (fin des données)');
        {$ENDIF}

lMakeErrFrameApercu4:
        DoSleep(600); Application.ProcessMessages;
        DoSleep(500); Application.ProcessMessages;
        DoSleep(300); Application.ProcessMessages;

        if iRedo > 3 then begin
           Result := -1;
           FInLogin := false;
           FRemoteURLGameDir := '';
           exit;
        end;

        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - Nouvelle tentative...');
        {$ENDIF}
        goto lRedoFrameApercu4;


     end else if  (FParserApercu.ParseBuffer(sPageWeb) = false) then begin
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserApercu Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
           DoDebug(sPageWeb);
           DoDebug('ProceedLogin - FParserApercu Echec (StatusCode:' + IntToStr(FsockHTTP.StatusCode) + ')');
        {$ENDIF}

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_APERCU);
          {$ENDIF}

        Result := CNT_ERROR_PARSING;
        exit;

     end;

     if FParserApercu.IsValidHeader = false then begin
        // header invalide, donc page web invalide
        {$IFDEF DEBUG}
           DoDebug('ProceedLogin - FParserApercu Echec - Header invalide');
           DoDebug(sPageWeb);
        {$ENDIF}

          {$IFDEF DEBUGFILE_WHEN_ECHEC}
             DebugWebPage(sPageWeb, CNT_DEBUGFILE_APERCU);
          {$ENDIF}

        Result            := CNT_ERROR_PARSING;
        FRemoteURLGameDir := '';
        FInLogin := false;
        exit;
     end;


     // Gère les cookies
     FCookies.ParseHeader(FsockHTTP.RcvdHeader);
*)


     // La planète mère est donc:
     // FParserApercu.cHeader.Planete
     // On extrait le pointeur vers cette planète, car il se peut qu'elle
     // existe déjà (pour une mise à jour par exemple)
(*     curPlanete := FPlaneteList.GetPlanete(FParserApercu.cHeader.Planete);
     if curPlanete = nil then begin
        curPlanete := TPlaneteInfo.Create;
        FPlaneteList.Add(curPlanete);
     end;
*)



     if curPlanete = nil then begin
        // echec de login
        Result := -399;
        exit;
     end;

     
     // ATTENTION: C'est après le parsing que l'on définit l'url de la page
     // sinon les liens vers les autres planète ne seront pas complet
     //FParserApercu.SetURLOfThisPage(FParserApercu.URLOfThisPage);
     FParsingPages.pApercu.SetFullURLFromBase(sHTTP);



     {$IFDEF DEBUG}
        curPlanete.DebugProc := FDebugProc;
     {$ENDIF}



     // sauvegarde l'existance des officiers
     FExistOfficier := FParsingPages.pHeader.ExistOfficier;


     // Planète mère
     curPlanete.FIsPlanetMere        := true;
(*   curPlanete.FNom           := cApercu.NomPlanete;
     curPlanete.FNbCasesOccupees := cApercu.CasesOccupees;
     curPlanete.FNbCasesTotales  := cApercu.CasesTotales;
     curPlanete.FLocation      := cApercu.cHeader.Planete;
     curPlanete.FLastRessources     := cApercu.cHeader.CurrRessource;
     curPlanete.FLastRessourcesDate := DateTimeToUnix(Now);
*)

     curPlanete.SendDebugAllPlanetInfo;





     // Valeur a AJOUTER (ou soustraire si la valeur est négative)
     // à l'heure obtenu en parsant les pages web (comme flotte)
     // pour obtenir une heure locale
     FDifferenceHeureLocaleHeureServeur := curPlanete.FLastRessourcesDate - FParsingPages.pApercu.ServeurDate;




     if FExistOfficier then begin
        // officier détecté...
        {$IFDEF DEBUG}
            {$IFDEF OFFICIER_OK}
                  if AllowToWorkWithOfficier = false then begin
                     sTmp := _('ProceedLogin - Officier détecté');
                     DoDebug('~~~~~~~~~');
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug('~~~~~~~~~');

                     sTmp := _('ProceedLogin - Les officiers étant très performant (et très cher) ils n''ont pas besoin de l''aide du robot');
                     DoDebug('~~~~~~~~~');
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug('~~~~~~~~~');

                     sTmp := _('ProceedLogin - Le robot n''effectuera aucune tache sur votre compte');
                     DoDebug('~~~~~~~~~');
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug(sTmp);
                     DoDebug('~~~~~~~~~');
                  end;

            {$ELSE}
                  sTmp := _('ProceedLogin - Officier détecté');
                  DoDebug('~~~~~~~~~');
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug('~~~~~~~~~');

                  sTmp := _('ProceedLogin - Les officiers étant très performant (et très cher) ils n''ont pas besoin de l''aide du robot');
                  DoDebug('~~~~~~~~~');
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug('~~~~~~~~~');

                  sTmp := _('ProceedLogin - Le robot n''effectuera aucune tache sur votre compte');
                  DoDebug('~~~~~~~~~');
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug(sTmp);
                  DoDebug('~~~~~~~~~');
            {$ENDIF}

        {$ENDIF}


        {$IFDEF OFFICIER_OK}
            if AllowToWorkWithOfficier = false then begin
               Result := -681;
            end else begin
               goto lLoginOk;
            end;

        {$ELSE}
           Result := -68;
        {$ENDIF}

     end else begin
lLoginOk:
        // Met à jour la dernière page dl
        //FLastPageWebDL := cApercu;

        
        DoSleep(500);

        Result := 1;
     end;


     FDateMenuNbError     := 0;
     FMustReloginDetected := false;
     FNextDateToRelog     := 0;

     if Result > 0 then begin
        // sauvegarde la page d'accueil
        sPageWeb := GetCacheLoginPagePath;

        try
          FStream := TFileStream.Create(sPageWeb, fmCreate);
        except
          FStream := nil;
        end;

        if FStream <> nil then begin
           FStream.Write(sPageWebAccueilLogin[1], length(sPageWebAccueilLogin));
           FStream.Free;
        end;

     end;

     FInLogin := false;


end;

function TPlayerGestion.DirectLoginPreloadCachePage: boolean;
var sDCStream: TFileStream;
    fPath: string;
begin

     fPath := GetCacheLoginPagePath;


       if FileExists(fPath) then begin

          try
            sDCStream := TFileStream.Create(fPath, fmOpenRead);

            SetLength(LoginLocalWebPage, sDCStream.Size);

            sDCStream.Read(LoginLocalWebPage[1], sDCStream.Size);

            sDCStream.Free;

            // Laisse le soin à la fonctionne appellante de définir ce flag
            //LoginUseLocalWebPage := true;

          except
            DoDebug('Lecture de la page de direct login impossible (cache)');
            if sDCStream <> nil then begin
               sDCStream.Free;
            end;
          end;


       end else begin
          DoDebug('Direct login file inexistant (cache): ' + fPath);
       end;
end;

function TPlayerGestion.GetCacheLoginPagePath: string;
begin
    Result := '';

        if Conf.LangageUni <> '' then begin
           Result := FDebugWebPageDossier + 'cache-' + Conf.LangageUni + '.login.txt';
        end else begin
           Result := FDebugWebPageDossier + 'cache' + '.login.txt';
        end;

end;


{$IFDEF DEBUG}
   procedure TPlayerGestion.DoDebugStrings(x: TStrings);
   var i: integer;
   begin
       if x.Count <= 0 then begin
          exit;
       end;

       for i := 0 to x.Count - 1 do begin
          DoDebug(x.Strings[i]);
       end;

   end;
   procedure TPlayerGestion.DoDebug(const Msg: string);
   begin
       if Assigned(FDebugProc) then
          FDebugProc(Msg);

   end;
{$ENDIF}

procedure TPlayerGestion.DoSleep(const Duree: integer);
var i, max: integer;
begin

    max := GetTickCount + Duree;

    repeat
       Application.ProcessMessages;
       Sleep(2);
       
    until GetTickCount > max;


end;


const
   CNT_SAVE_SECTION_GENERAL = 'general';
   CNT_SAVE_FActionDateFinRecherche   = 'aFinRecherche';




procedure TPlayerGestion.LoadLigne(Ligne: string);
var xPos: integer;
    key: string;
begin

   xPos := pos('=', Ligne);
   if xPos = 0 then exit;

   key := copy(Ligne, 1, xPos - 1);
   System.Delete(Ligne, 1, xPos);

   if SameText(key, CNT_SAVE_FActionDateFinRecherche) then begin
      //FActionDateFinRecherche := StrToIntDef(Ligne, 0);
   end;


end;


function TPlayerGestion.LoadFromFile(Fichier: string): integer;
var F: TextFile;
    i: integer;
    pElement: TPlaneteInfo;
    s: string;
    InGeneral: integer;
begin

    {$IFDEF DEBUG}
       DoDebug('Chargement - Fichier: ' + Fichier);
    {$ENDIF}


    FFichier := Fichier;
    
    if FileExists(Fichier) = false then begin
       {$IFDEF DEBUG}
           DoDebug('Fichier introuvable');
       {$ENDIF}

       Result := -2;
       exit;
    end;

    Result := -1;

    AssignFile(F, Fichier);
    
    {$I-}
    ReSet(F);
    {$I+}

    // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
    if NoT(IOResult = 0) then begin
       Result := -1;
       exit;
    end;

    InGeneral := 0;



    While NoT(EoF(F)) do begin
       // Lit une ligne
       ReadLn(F, s);

       s := trim(s);
       if s = '' then Continue;
       if s[1] = '#' then Continue;
       if s[1] = '/' then Continue;


       if s[1] = '[' then begin
          // Nouvelle section
          if InGeneral = 1 then begin
             // On est passé au planète
             pElement := TPlaneteInfo.Create;
             i := pElement.LoadFromFile(F, s);

             if i < 0 then begin
                {$IFDEF DEBUG}
                    DoDebug('Erreur chargement');
                {$ENDIF}

                pElement.Free;
                break;
             end else begin

                {$IFDEF DEBUG}
                   pElement.DebugProc := FDebugProc;
                {$ENDIF}

                FPlaneteList.Add(pElement);
             end;
          end;

          if InGeneral = 0 then
             InGeneral := 1;

       end else begin
           // Charge la ligne
           LoadLigne(s);
       end;


    end;

    Result := FPlaneteList.Count;
    
    // Fermeture du fichier
    CloseFile(F);

    {$IFDEF DEBUG}
       DoDebug('Fin de Chargement');
    {$ENDIF}
end;


function TPlayerGestion.SaveToFile(Fichier: string): integer;
var F: TextFile;
    i: integer;
    pElement: TPlaneteInfo;
begin

    Result := -2;
    if Fichier = '' then Fichier := FFichier;

    if Fichier = '' then begin
       exit;
    end;

    AssignFile(F, Fichier);
    
    {$I-}
    ReWrite(F);
    {$I+}
    
    // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
    if NoT(IOResult = 0) then begin
       Result := -1;
       exit;
    end;

    // Ecrit l'header
    WriteLn(F, '# Fichier de configuration');
    WriteLn(F, '');
    WriteLn(F, '[' + CNT_SAVE_SECTION_GENERAL + ']');


    //WriteLn(F, format('%s=%d', [CNT_SAVE_FActionDateFinRecherche, FActionDateFinRecherche]));



    WriteLn(F, '');


    for i := 0 to FPlaneteList.Count - 1 do begin
        pElement := FPlaneteList.Items[i];

        //
        // Ecriture ici
        //
        pElement.SaveToFile(F);

    end;
    
    // Résultat
    Result := FPlaneteList.Count;

    WriteLn(F, '');
    WriteLn(F, '# Fin du fichier');
    WriteLn(F, '');

    // Ferme le fichier
    CloseFile(F);



end;

constructor TPlayerGestion.Create;
begin
    inherited Create;

    Conf :=  TProfilsAttack.Create;



     FPlaneteList := TListPlanet.Create;

     FScanneurCommum := TEasyXmlScanner.Create(nil);
     FScanneurCommum.Normalize := true;

     // Client HTTP
     FsockHTTP := THttpCli.Create(nil);

     //FsockHTTP.Agent := 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4';
     //FsockHTTP.Agent := 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7';
     FsockHTTP.Agent := 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7';

 

     FsockHTTP.Accept := 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
     FsockHTTP.AcceptLanguage := 'en-us,en;q=0.5';

     //FLogingUniversListPage := 'http://ogame.fr/portal/index.php?frameset=1';
     FLogingUniversListPage := 'http://ogame.fr/home.php';

     FLogingUniversListPageReferenceLink := 'http://ogame.fr/';

     //FLoginDirectOnGameServeur := false;
     //FLoginDirectURLServeur    := '';

     
     // Utilise un tampon pour ne pas transiter par un fichier
     FsockHTTP.UtiliserTampon := true;

     // Le lien de référence ne doit pas être n'importe quoi, et doit
     // donc être géré par la classe
     modGestionDonwload_AUTO_REFERER := False;


     // Sauvegarde des cookies
     FCookies := TCollectionCookieInfos.Create;

     // Pour pouvoir se logger
     FParserGetLogIn := TParsingLogInPage.Create(FScanneurCommum);

     // Pour connaitre la page de redirection, bien que
     // ce soit toujours la même, cela permet de savoir
     // surtout si le login s'est bien effectué
     FParserAfterPostLogin := TParsingAfterLogInPage.Create;

     // Après avoir été redirigé, on tombe sur une frame
     // qui sépare l'écran en deux, le menu à gauche, et
     // le reste à droite.
     FParserFrame := TParsingFrameSet.Create;

     // Pour connaitre les liens du menu, et pouvoir ainsi
     // se déplacer efficacement
     //FParserMenu := TParsingMenuLeft.Create;

     // Pour la page de ressources
     //FParserRessource := TParsingPageRessource.Create(FScanneurCommum);

     // Pour la page d'aperçu
     //FParserApercu := TParsingAppercu.Create(FScanneurCommum);

     // Pour la page batiment, recherche, station spatial, défense
     //FParserElement := TParsingBatiment.Create(FScanneurCommum);

     //FParserStats   := TParsingPlayerStats.Create(FScanneurCommum);

     //FParserGalaxie := TParsingGalaxie.Create(FScanneurCommum);

     //FParserFlotte1Vaisseaux      := TParsingFlotte1_ChoixVaisseaux.Create(FScanneurCommum);
     //FParserFlotte2Destination    := TParsingFlotte2_ChoixDestination.Create(FScanneurCommum);
     //FParserFlotte3OrdreRessources:= TParsingFlotte3_OrdreEtRessources.Create(FScanneurCommum);
     //FParserFlotte4Confirmation   := TParsingFlotte4_ConfirmationEnvoi.Create(FScanneurCommum);

     //FParserMessagesList          := TParsingMessagesList.Create(FScanneurCommum);

     //FLastPageWebDL := nil;
     FDateMenuLoad := -1;

     // Create critical section object:
    InitializeCriticalSection(ReadWriteCS);
    FInTimer := false;
    FInLogin := false;

    FJobOccupation := jobpAucun;

    FDontDLAppercuPageOnChangePlanet := false;

    FProcRecolteArret := false;

        // Nombre de verouillage
        FLockTimerCount  := 0;

        // Nombre d'entrée dans le timer
        FEnterTimerCount := 0;

    {$IFDEF DEBUGFILE_FLAG}
       FDebugWebPageActive  := false;
       FDebugWebPageDossier := '';

       {$IFDEF DEBUGFILE_WHEN_SUCCESS}
           FDebugWebPageActiveWhenSuccess := false;
       {$ENDIF}
    {$ENDIF}



    DossierRapportCombat := '';

    LoginUseLocalWebPage := false;
    LoginLocalWebPage := '';


{$IFDEF OFFICIER_OK}
        // par défaut ça fonctionne
        AllowToWorkWithOfficier := true;
{$ENDIF}



    FParsingPages := TParsingGestion.Create(FScanneurCommum);



    Clear(true);
end;

destructor TPlayerGestion.Destroy;
var i: integer;
    Planete: TPlaneteInfo;
begin

        if FPlaneteList.Count > 0 then begin
           for i := FPlaneteList.Count - 1 downto 0 do begin
               Planete := FPlaneteList.Items[i];

               if Planete <> nil then begin
                  Planete.Free;
                  FPlaneteList.Items[i] := nil;
               end;
           end;
        end;

        FPlaneteList.Free;


        // Client HTTP
        FsockHTTP.Free;

        // Sauvegarde des cookies
        FCookies.Free;

        FParsingPages.Free;

        // Pour pouvoir se logger
        FParserGetLogIn.Free;

        // Pour connaitre la page de redirection, bien que
        // ce soit toujours la même, cela permet de savoir
        // surtout si le login s'est bien effectué
        FParserAfterPostLogin.Free;

        // Après avoir été redirigé, on tombe sur une frame
        // qui sépare l'écran en deux, le menu à gauche, et
        // le reste à droite.
        FParserFrame.Free;

        //FParserStats.Free;

        // Pour connaitre les liens du menu, et pouvoir ainsi
        // se déplacer efficacement
        //FParserMenu.Free;

        // Pour la page de ressources
        //FParserRessource.Free;

        // Pour la page d'aperçu
        //FParserApercu.Free;

        // Pour la page batiment, recherche, station spatial, défense
        //FParserElement.Free;

        // Galaxie
        //FParserGalaxie.Free;

        // Les flottes
        //FParserFlotte1Vaisseaux.Free;
        //FParserFlotte2Destination.Free;
        //FParserFlotte3OrdreRessources.Free;
        //FParserFlotte4Confirmation.Free;

        //FParserMessagesList.Free;

        FScanneurCommum.Free;

        if Conf <> nil then begin
           Conf.Free;
        end;

        Conf := nil;

        DeleteCriticalSection(ReadWriteCS);

        inherited Destroy;
end;


end.
